RubyGems Are The Foundation Of Success
March 31, 2015 Aaron Bartell
In my previous article, I discussed a RubyGem named xmlservice but didn’t really dive into what Gems are, why they exist, and how we can use them to save a tremendous amount of time. That’s what this article is about. But before we dive into geekdom, it is worth digressing into a perspective I’ve gained by observing the top open-source-language camps.
I often get asked “Why Ruby? Isn’t XYZ language more popular?” Usually the XYZ language is PHP or Java, as I think it is safe to say PHP is the most popular web language out there and Java owns a lot of space in many enterprises. Add to that the tremendous amount of open-source PHP and Java on the Internet available for anyone to freely make use of and it leaves a person rightly wondering why anything else should be considered. The issue is the majority of this open source takes different paths to how people can use it, download, install, implement, and subsequently maintain. This is where the Ruby community has taken a different path, a path that recognized the vast inefficiencies of sharing code libraries, and created a remedy named RubyGems.
Wikipedia.org describes RubyGems as follows: RubyGems (previously known as Gemcutter) is a package manager for the Ruby programming language that provides a standard format for distributing Ruby programs and libraries (in a self-contained format called a “Gem”), a tool designed to easily manage the installation of Gems, and a server for distributing them. RubyGems was created in about November 2003 and is now part of the standard library from Ruby version 1.9.
To put that into RPG-speak, imagine placing many RPG programs into a *SAVF object and having that be easily published and distributed via a community agreed upon site. Then also imagine people making use of your library by entering a simple command like RPGPKG INSTALL(‘RPGMAIL’), which would go out to the community site, download the *SAVF, do a RST* to place compiled object and source into a library, and finally, look at a config file for other dependencies and repeat the processing of downloading and restoring. That’s what RubyGems accomplishes, though for Ruby and not RPG.
Probably the best way to learn about RubyGems is to create your own. The good thing is that creating and sharing a custom Gem is very easy, as documented at the RubyGem.org site. Here is my “hola” Gem produced from that tutorial. As you can see from that tutorial the Ruby community has implemented a very efficient way of not only packaging code but also sharing it.
The xmlservice Gem used in the previous article came installed with PowerRuby so that didn’t give us a good feel for how to obtain a new Gem. To give example of Gem installation we will put ourselves to the task of creating PDFs using the Ruby language. As always, Google is your friend and we quickly find PrawnPDF.
Another part of this task is we don’t want this new Gem to be installed in the global area of the machine (i.e., /PowerRuby/prV2R0/lib/ruby/gems/2.0.0) and should instead install it in our own personal directory (i.e., /home/aaron/gemsets/general). To accomplish this we first need to open a QP2TERM session and create the folders, as shown below. Make sure to replace ‘aaron’ with your own profile. Note the -p option that declares that parent directories should also be created if they don’t exist.
$ mkdir -p /home/aaron/gemsets/general
Next we need to alter the GEM_HOME and GEM_PATH environment variables. Think of environment variables as being similar to a job-wide data area (*DTAARA) that any program within the job can use to store or obtain values. The GEM_HOME environment variable is used both for the installation directory of new Gems. The GEM_PATH environment variable is used in similar nature to IBM i library lists–it declares which directories should be reviewed for resolving Gems at runtime and is processed from left to right, so it will look in /home/aaron/gemsets/general first.
$ export GEM_HOME=/home/aaron/gemsets/general $ export GEM_PATH=/home/aaron/gemsets/general:/PowerRuby/prV2R0/lib/ruby/gems/2.0.0
To review all of the RubyGem settings, we can run the gem env command as shown below. Notice how INSTALLATION DIRECTORY is set to the value specified for GEM_HOME. Also notice how GEM PATHS has two entries, the ones we specified for GEM_PATH.
$ gem env RubyGems Environment: - RUBYGEMS VERSION: 2.0.14 - RUBY VERSION: 2.0.0 (2014-10-27 patchlevel 594) [powerpc-aix220.127.116.11] - INSTALLATION DIRECTORY: /home/aaron/gemsets/general - RUBY EXECUTABLE: /PowerRuby/prV2R0/bin/ruby - EXECUTABLE DIRECTORY: /home/aaron/gemsets/general/bin - RUBYGEMS PLATFORMS: - ruby - powerpc-aix-6 - GEM PATHS: - /home/aaron/gemsets/general - /PowerRuby/prV2R0/lib/ruby/gems/2.0.0 - GEM CONFIGURATION: - :update_sources => true - :verbose => true - :backtrace => false - :bulk_threshold => 1000 - REMOTE SOURCES: - https://rubygems.org/
At this point we can now install the Prawn Gem by running command gem install prawn. When we install a Gem, it first checks to see if the Gem is already installed and if not will retrieve it from RubyGems.org. The Prawn Gem has two dependencies–ttfunk and pdf-core–which RubyGems automatically downloaded and installed for us.
$ gem install prawn Fetching: ttfunk-1.4.0.gem (100%) Successfully installed ttfunk-1.4.0 Fetching: pdf-core-0.4.0.gem (100%) Successfully installed pdf-core-0.4.0 Fetching: prawn-1.3.0.gem (100%) Successfully installed prawn-1.3.0 Parsing documentation for ttfunk-1.4.0 Installing ri documentation for ttfunk-1.4.0 Parsing documentation for pdf-core-0.4.0 Installing ri documentation for pdf-core-0.4.0 Parsing documentation for prawn-1.3.0 Installing ri documentation for prawn-1.3.0 3 gems installed
To confirm where the Gem was installed we can use command gem list, as shown below.
$ gem list prawn -d *** LOCAL GEMS *** prawn (1.3.0) Authors: Gregory Brown, Brad Ediger, Daniel Nelson, Jonathan Greenberg, James Healy Homepage: http://prawn.majesticseacreature.com Licenses: RUBY, GPL-2, GPL-3 Installed at: /home/aaron/gemsets/general A fast and nimble PDF generator for Ruby
At this point you are ready to make use of the Gem. The below Ruby program gives a hello world style introduction to your first PDF.
require "prawn" Prawn::Document.generate("hello.pdf") do text "Hello World!" end
The best way to test new code is with irb (Interactive Ruby Shell), as we learned in Testing the Ruby Waters. Pasting the above code into irb gives us quick iterative development testing of the waters. The below will produce a PDF named hello.pdf with the contents of “Hello World!” in the current directory.
$ irb irb(main):001:0> require "prawn" => true irb(main):002:0> irb(main):003:0* Prawn::Document.generate("hello.pdf") do irb(main):004:1* text "Hello World!" irb(main):005:1> end => nil irb(main):006:0> quit
As you can see, this was an amazingly simple way to obtain new functionality on my machine for the betterment of my business.
This is one of the reasons why I really like Ruby, but the goodness of the Ruby environment and community doesn’t stop here. For example, you can install many different versions of the same Gem on a machine and sometimes it is important for a particular application to lock down to a specific version of a Gem. That’s where a tool named Bundler comes into play. It gives a simple way to specify the names and versions of all the Gems your application needs to make use of so you can be assured that what works in development also works in production. Stay tuned for more on Bundler.
Aaron Bartell is Director of IBM i Innovation for Krengel Technology, Inc. Aaron facilitates adoption of open source technologies on IBM i through professional services, staff training, speaking engagements, and the authoring of best practices within industry publications and www.litmis.com. With a strong background in RPG application development, Aaron covers topics that enable IBM i shops to embrace today’s leading technologies including Ruby on Rails, Node.js, Git for RPG source change management and RSpec for unit testing RPG. Aaron is a passionate advocate of vibrant technology communities and the corresponding benefits available for today’s modern application developers. Connect with Aaron via email at firstname.lastname@example.org. Aaron lives with his wife and five children in Southern Minnesota. He enjoys the vast amounts of laughter having a young family brings, along with camping and music. He believes there’s no greater purpose than to give of our life and time to help others.