• 20 hours
  • Medium

Free online content available in this course.

course.header.alt.is_video

course.header.alt.is_certifying

Got it!

Last updated on 10/4/17

Use Rubygems

Log in or subscribe for free to enjoy all this course has to offer!

 

If you're learning about Ruby, there's a good chance you've heard about Ruby on Rails, the most popular Ruby web development framework. You might know about other projects written in Ruby, such as Sass, Sinatra, or one of the thousands of other third-party libraries that projects such as these depend on.

Most languages have a system for downloading, updating, and importing third party libraries like these. In Ruby, that system is called RubyGems. You mostly interact with it through the CLI command gem..

To get started with the gem command, go to the command line and do:

$ gem help

You can see a few examples and a suggestion to use the help command to learn more. Let's try

$ gem help commands

You can see that gem has a lot of commands within it. Most of these fall into two use cases, publishing your own gems, and using gems other people have published.

First, let's look at using gems that other people have published.

A fun one is Artii, a lightweight ascii art generator. You can install it like this:

$ gem install artii

Once your shell tells you it has downloaded, let's create a new file called whoa.rb, and use the artii gem to make some ascii art!

require "artii"

arter = Artii::Base.new

puts arter.asciify("whoa")

So, how did this work? Remember require from last chapter? How are we able to use it without any path, or even file extension? To figure this out, let's look again at our $LOAD_PATH variable:

puts $LOAD_PATH

require "artii"

arter = Artii::Base.new

puts arter.asciify("whoa")

That's odd, we don't see anything about artii here. How is Ruby finding the gem when we call require?

Try moving the puts$LOAD_PATHcall so that it follows therequirecall:

whoa.rb

require "artii"

puts $LOAD_PATH

arter = Artii::Base.new

puts arter.asciify("whoa")

Now do you see it in the$LOAD_PATH? Interesting! Somehow, calling require actually changed the load path.

This is because Rubygems is doing some magic. Under the hood, when we call require and a file isn't found, Rubygems jumps in and says "maybe I can help". It then looks through our designated gem directories for any file called "artii" inside a "lib" directory in any of our installed gems. When Rubygems finds a file like that, it says "OK, you actually want this gem that has this file in it" and it goes back to Ruby and says "I think this is what they mean. Add this gem's lib directory to your load path and you'll be good."

To illustrate this, let's try a nasty hack.

In the output of$LOAD_PATH, maybe as the first item, you should see another gem, called "Did You Mean". This is a gem that's included by default with Ruby installations now, and it helps you by recommending fixes for syntax errors. We're not concerned with did_you_mean, except that it comes before artii in the$LOAD_PATHarray.

Let's create a new Ruby file inside the lib directory of the "did you mean" gem.

WAIT YOU CAN DO THAT?

Yes. Just take the path, exactly as it is output by our program, to the lib directory of the "did you mean" gem, and create a new file in that path using your text editor, called artii.rb:

Here's how I do it on my computer:

$ vim /Users/alegscogs/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/did_you_mean-1.0.0/lib/artii.rb
/Users/alegscogs/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/did_you_mean-1.0.0/lib/artii.rb

 

artii.rb

puts "what on earth is going on?"

Now, let's run whoa.rb again:

$ ruby whoa.rb

Interesting!

Our new file was run when we required "artii", outputting the string that that fileputs. Our artii gem is no longer in the load path, and we get an error when we try to reference it's code at the bottom of the file.

As you may have guessed, Ruby already hasdid_you_mean's lib directory in the load path, so it finds our rogue artii.rb file there when werequire "artii", and doesn't go look to Rubygems for help in loading it. This means the gem never gets activated, and artii's lib directory never gets added to our load path.

Before we go on, go back to our hacked artii.rb file and delete it, or we won't be able to require the artii gem in any of our Ruby code.

Build

The first command that you see in the list output by `gem help commands` is probably "build". "build" tells Rubygems to treat the directory where you presently are as a Rubygem, and try to build a distributable gem from it. Of course, to do this successfully, you'll have to have the right kinds of files, configuration, and program in the present directory. We're not going to get into building Rubygems in this course, but for now, understand that anyone, including you, can use these commands to create a gem that other users will be able to download via "gem install".

Gem executables

If you take a look at the README for the artii gem, you might notice that the instructions for running it first use the command "artii" to generate ascii art from the command line. You don't have to run this with Ruby, it "just works" from the command line. Somehow, installing the artii gem when you did "gem install artii" also added this ability to run "artii" from the command line. Let's have a look at that now. Somewhere in your terminal output from this chapter you should be able to find the path to the lib directory in your installation of the artii gem. If not, you can rerun whoa.rb to get it. Navigate to that lib directory and then move up one directory from there. This is the artii gem's home directory in your file system. If you're having trouble finding it, it should look like the directory at https://github.com/miketierney/artii.

There are a bunch of special files here. The one we're interested in is called artii.gemspec. .gemspec is a file that has to be present in any Rubygem. It is a Ruby file that describes what's necessary to publish this gem. At the top there should be a line that saysGem::Specification.new do |s|or something similar. Under there is an indented list of configuration items, each of which is assigning some value to the specification object being created by theGem::Specification.newinitializer method. Look down the list for a line that assigns a value called "executables". At the time I'm writing, it's on line 17 in this file, and it looks like this:

s.executables = ["artii"]

This is how the gem tells your Rubygems that it wants to install an executable command called artii on your system. Rubygems in turn will look inside a directory called bin in the artii gem. If you look in that directory, you'll see the artii executable command file there. that file looks like this in my version:

bin/artii

#!/usr/bin/env ruby

require 'artii'

begin
  a = Artii::CLI.new *ARGV.dup
  puts a.output
rescue StandardError => e
  puts "Something has gone horribly wrong!"
  puts "Artii says: #{e.message}"
  # puts e.backtrace
end

This is an executable Ruby file. That means you can call this file from the command line like a CLI command, without using the Ruby command to run it. You can make your Ruby files executable like this by adding that line at the top:

#!/usr/bin/env ruby

Let's break that line down for a moment. It's actually a little shell script, hidden from Ruby because it happens to start with a Ruby comment character "#".

Together, the first two characters are sometimes called "shebang", which stands for "sharp" and "bang", respectively. The shebang tells the shell that it can execute this file by using the command which follows. The /usr/bin/env part tells it that it should look in the current path for the command that comes after, and, finally, the word Ruby is the command that the shell should use to run this file. tl;dr is that this line tells the shell to use Ruby to run this file as a CLI command.

 

Security: Be careful installing gems!

Rubygems have the ability to install executable files in your system that can overwrite known commands. This means that a malicious person could easily publish a gem designed to attack your computer when you download it, by overwriting a common command, such as "cd" or "cat", and having that command do something malicious to your computer when you run it. In order to avoid this, make sure you understand what you're downloading when you run "gem install". Read the .gemspec file and look at the executables being installed. This will help you understand the software you're using better and will keep you a little bit safer.

https://m4.rkw.io/blog/abusing-rubygems-for-fun-and-profit.html

Example of certificate of achievement
Example of certificate of achievement