Back-end Engineering Articles

I write and talk about backend stuff like Ruby, Ruby On Rails, Databases, Testing, Architecture / Infrastructure / System Design, Cloud, DevOps, Backgroud Jobs, and more...

Twitter:
@daniel_moralesp

2019-03-15

What is a Ruby Gem?

So far, we have advanced in some initial concepts about learning Ruby and other stuff like Versioning, Installing Ruby, RVM, and IRB; now, let's welcome an essential idea in the programming world: Packages.

Package or Library


In computer science, a package or library is a collection of non-volatile resources used by computer programs, often for software development. These may include configuration data, documentation, help data, message templates, pre-written code and subroutines, classes, values, or type specifications. 

A library is a collection of implementations of behavior, written in terms that have a well-defined interface by which the behavior is invoked. For instance, people who want to write a higher-level program can use a library to make system calls instead of implementing those system calls over and over again.

Note: read this post if you want to know more about packages or libraries

This jargon could be a little confusing if you're a beginner, so let's simplify the terms and make an analogy. Let's suppose that you want to create a web page and allow people to register and then log in via web browser. 

The good news is that you don't have to make everything from scratch because someone else encountered this very same challenge in the past. 

So they decided to encapsulate it and distribute it for free for other people, which is fantastic! But probably at this point, you could have some concerns and questions about this kind of solution:

    • * Why is it a bad idea to write everything from scratch if I'm learning and want to practice my skills?
    • * Are there packages or libraries for every possible use case?
    • * Why do people do this for free?
    • * How secure is it to use other people's code?
    • * Does this concept apply to any programming language?

  • So let's try to answer these questions.


Why is it a bad idea to write everything from scratch if I'm learning and want to practice my skills?

You don't want to reinvent the wheel and create everything from scratch with all the complexities that this could imply. But, on the other hand, you have to consider that maybe someone else solved this very same problem in the past and that they distributed that solution for free. 

If you're just learning, there are better places to invest your time. For example, let's suppose you want to implement an authentication method for a web app, so if you have enough time, resources, and knowledge, you can do it from scratch... 

but if you don't have all of these prerequisites, it's better to look for a package or library that can implement this for you. This same philosophy applies to repetitive use cases under the problems you want to solve with code. This is the root for the next question...

Are there packages or libraries for every possible use case?

It depends. Plenty of solutions are already implemented for everyday use cases like authentication, testing, or background jobs in web apps, so you don't have to do it from scratch. But if you want to create something unique inside your web app (just in that case), you have to create your own solution. 

One time, I heard somebody saying that to create a web page that does something innovative (startup company), you can do it with almost 80% with libraries, and the other 20% will be your proprietary code. For this reason, knowledge about libraries is so necessary because you can create almost 80% out of 100% of it using libraries written by others in the past. This also means that there are packages for nearly every possible use case, but not for all of them.

Why do people do this for free?

Because there is a concept called "Open-source software (OSS)." This is one of the most powerful concepts in computer software: Open-source software (OSS) is software that is released under a license in which the copyright holder grants users the rights to use, study, change, and distribute the software and its source code to anyone and for any purpose.

Open-source software may be developed in a collaborative public manner. Open-source software is a prominent example of open collaboration, meaning any capable user can participate online in development, making the number of possible contributors indefinite. In addition, the ability to examine the code facilitates public trust in the software.

Open-source software development can bring in diverse perspectives beyond a single company. A 2008 report by the Standish Group stated that the adoption of open-source software models has resulted in savings of about $60 billion per year for consumers.

Open source code can be used for studying and allows capable end-users to adapt the software to their personal needs in a similar way user scripts and custom style sheets allow for websites... 

And eventually, publish the modification as a fork for users with similar preferences and directly submit possible improvements as pull requests.

For more info about Open Source, click here.


How secure is it to use other people’s code?

This is a good question, and it is fair to say that you'll never be 100% protected, but you can take measures when using 3rd Party packages or libraries. The first thing is to be sure that you're in the latest versions of the software because older versions can have security vulnerabilities given the lack of support by the community. 

Another essential thing to check is the Github repository and see how active the maintainers are releasing new code and bug fixtures. Again, a good idea is to use well-known packages or libraries, measured by the number of downloads. But, again, you can see all of that in the GitHub repository.

Does this concept apply to any programming language?

Yes, this concept of Package or Library applies to almost all modern programming languages. For example, in Ruby, you can find RubyGems as a package manager along with Bundler. In javascript, you can discover NPM, and in Python, you'll see Conda or PIP. 

These tools work as central repositories, where package or library creators can deploy their code, and the users can download it and install it. So it works like a big marketplace for Packages and Libraries. 

Once these main questions are answered, we can go ahead...

So, what is a Ruby Gem?

Gem is the name that Ruby creators give to the open-source packages or libraries built with Ruby code, so if you find a package that deals with the user authentication in a webpage, we call this package a Gem! 

So it's time to introduce the most essential and popular Ruby Gem: Rails.

Rails itself is a Ruby package or library created by David Heinemeier Hansson, who publicly released it in 2004. It helped hundreds of people create web pages efficiently, quickly, and affordable. 

It's simple to understand why it is so popular. Each time you create a web page, you have to go through consecutive and repetitive steps: create a web server, generate the skeleton (Routes, Models, Views, Controllers, etc.) and have every file organized in the same way and well connected between them. Because it is a repetitive and standard process, you can encapsulate it in different files and code, synchronize everything and make it easy for public use. Rails are the best example of a package or library.

Note: later in a new blog post, we'll be writing about how to install Ruby on Rails and how to use it in detail

The site where you can find all the Ruby gems is https://rubygems.org/.

Unfortunately, this site does not organize gems by use case, but they just organize things alphabetically: https://rubygems.org/gems, but with a quick search in Google, you could find a gem according to your use case; for instance, you can ask Google following keywords:

  • * Ruby gem for user authentication
  • * Ruby gem for testing
  • * Ruby gem for background jobs

I think that you got it, it's a matter of search, and probably you'll find a gem for almost all use cases. Here I want to share an excellent resource to see a list of good Ruby gems: https://www.monocubed.com/ruby-on-rails-gems/.

How to install a Ruby Gem?

You've two options to install a Ruby Gem; the first is globally in your machine, and the second is per project. 

Let's go again to the RubyGems site: https://rubygems.org/, and then we'll type "Devise" on the search bar.


We'll choose the first one: "Devise," and we can see that they have at this moment more than 115 million downloads, so it's pretty popular. 


Let's click on "Devise" and then see the following screenshot.


We have some information here, but the most important at this very moment is this one.


At the right panel, we can see the links for GEMFILE and INSTALL. We just want to install globally, not per project, because we don't have any project yet (we'll do that in the next blog posts), so the link that helps us now achieve this installation is the one that is under the INSTALL section. So if you copy that text in your clipboard, this is the code.

gem install devise

That command is the one we've to type in our machine. So, let's do it on our Linux machine (remember that we've created a different machine, so please refer to the previous blog posts). 

Note: We have to run this command outside the IRB console; if you run this command inside the IRB console, you'll get an error. To exit the IRB console, just type "exit."

So let's type the subsequent commands.

$ ssh -p 22 -i ~/.ssh/ubuntu-webserver-rails.pem [email protected]
$ gem install devise

Output

Fetching rack-2.2.3.gem
Fetching zeitwerk-2.5.3.gem
Fetching warden-1.2.9.gem
Fetching thor-1.2.1.gem
Fetching method_source-1.0.0.gem
Fetching concurrent-ruby-1.1.9.gem
Fetching tzinfo-2.0.4.gem
Fetching i18n-1.8.11.gem
Fetching activesupport-7.0.1.gem
Fetching nokogiri-1.13.0-x64-mingw32.gem
Fetching crass-1.0.6.gem
Fetching loofah-2.13.0.gem
Fetching rails-html-sanitizer-1.4.2.gem
Fetching rails-dom-testing-2.0.3.gem
Fetching rack-test-1.1.0.gem
Fetching erubi-1.10.0.gem
Fetching devise-4.8.1.gem
Fetching builder-3.2.4.gem
Fetching actionview-7.0.1.gem
Fetching actionpack-7.0.1.gem
Fetching railties-7.0.1.gem
Fetching responders-3.0.1.gem
Fetching orm_adapter-0.5.0.gem
Fetching bcrypt-3.1.16.gem
Successfully installed rack-2.2.3
Successfully installed warden-1.2.9
Successfully installed zeitwerk-2.5.3
Successfully installed thor-1.2.1
Successfully installed method_source-1.0.0
Successfully installed concurrent-ruby-1.1.9
Successfully installed tzinfo-2.0.4
Successfully installed i18n-1.8.11
Successfully installed activesupport-7.0.1
Successfully installed nokogiri-1.13.0-x64-mingw32
Successfully installed crass-1.0.6
Successfully installed loofah-2.13.0
Successfully installed rails-html-sanitizer-1.4.2
Successfully installed rails-dom-testing-2.0.3
Successfully installed rack-test-1.1.0
Successfully installed erubi-1.10.0
Successfully installed builder-3.2.4
Successfully installed actionview-7.0.1
Successfully installed actionpack-7.0.1
Successfully installed railties-7.0.1
Successfully installed responders-3.0.1
Successfully installed orm_adapter-0.5.0
Temporarily enhancing PATH for MSYS/MINGW...
Building native extensions. This could take a while...
Successfully installed bcrypt-3.1.16
Successfully installed devise-4.8.1
Parsing documentation for rack-2.2.3
Installing ri documentation for rack-2.2.3
Parsing documentation for warden-1.2.9
Installing ri documentation for warden-1.2.9
Parsing documentation for zeitwerk-2.5.3
Installing ri documentation for zeitwerk-2.5.3
Parsing documentation for thor-1.2.1
Installing ri documentation for thor-1.2.1
Parsing documentation for method_source-1.0.0
Installing ri documentation for method_source-1.0.0
Parsing documentation for concurrent-ruby-1.1.9
Installing ri documentation for concurrent-ruby-1.1.9
Parsing documentation for tzinfo-2.0.4
Installing ri documentation for tzinfo-2.0.4
Parsing documentation for i18n-1.8.11
Installing ri documentation for i18n-1.8.11
Parsing documentation for activesupport-7.0.1
Installing ri documentation for activesupport-7.0.1
Parsing documentation for nokogiri-1.13.0-x64-mingw32
Installing ri documentation for nokogiri-1.13.0-x64-mingw32
Parsing documentation for crass-1.0.6
Installing ri documentation for crass-1.0.6
Parsing documentation for loofah-2.13.0
Installing ri documentation for loofah-2.13.0
Parsing documentation for rails-html-sanitizer-1.4.2
Installing ri documentation for rails-html-sanitizer-1.4.2
Parsing documentation for rails-dom-testing-2.0.3
Installing ri documentation for rails-dom-testing-2.0.3
Parsing documentation for rack-test-1.1.0
Installing ri documentation for rack-test-1.1.0
Parsing documentation for erubi-1.10.0
Installing ri documentation for erubi-1.10.0
Parsing documentation for builder-3.2.4
Installing ri documentation for builder-3.2.4
Parsing documentation for actionview-7.0.1
Installing ri documentation for actionview-7.0.1
Parsing documentation for actionpack-7.0.1
Installing ri documentation for actionpack-7.0.1
Parsing documentation for railties-7.0.1
Installing ri documentation for railties-7.0.1
Parsing documentation for responders-3.0.1
Installing ri documentation for responders-3.0.1
Parsing documentation for orm_adapter-0.5.0
Installing ri documentation for orm_adapter-0.5.0
Parsing documentation for bcrypt-3.1.16
Installing ri documentation for bcrypt-3.1.16
Parsing documentation for devise-4.8.1
Installing ri documentation for devise-4.8.1
Done installing documentation for rack, warden, zeitwerk, thor, method_source, concurrent-ruby, tzinfo, i18n, activesupport, nokogiri, crass, loofah, rails-html-sanitizer, rails-dom-testing, rack-test, erubi, builder, actionview, actionpack, railties, responders, orm_adapter, bcrypt, devise after 89 seconds
24 gems installed

Screenshot of the output

Because it is the first time we install a gem, we'll end up with other dependencies installed. As you can see, Devise itself uses other 24 gems as dependencies. We talked about Dependency Managers in a previous post, so you can check it out to understand this more in detail.

Now maybe you're asking about what makes the "Devise" gem so popular? Devise deals with user authentication in web apps, and if you think a bit about it, it is a repetitive process, something you'll need almost always in your web apps, and you don't have to write all this functionality from scratch. So that's why it is so popular. 

This is enough for this post; next time, we'll use Ruby Gems a lot, so if you don't get it now, don't worry; just keep your learning process.

Thanks for reading 
Daniel Morales