Ruby Archives - Stackify Wed, 10 Apr 2024 05:57:52 +0000 en-US hourly 1 https://wordpress.org/?v=6.4.4 https://stackify.com/wp-content/uploads/2023/02/favicon.png Ruby Archives - Stackify 32 32 How to Rescue Exceptions in Ruby https://stackify.com/rescue-exceptions-ruby/ Thu, 21 Sep 2023 11:25:01 +0000 https://stackify.com/?p=23441 Exceptions are a commonly used feature in the Ruby programming language. The Ruby standard library defines about 30 different subclasses of exceptions, some of which have their own subclasses. The exception mechanism in Ruby is very powerful but often misused. This article will discuss the use of exceptions and show some examples of how to deal with them.

What is an exception?

An exception represents an error condition in a program. Exceptions provide a mechanism for stopping the execution of a program. They function similarly to “break,” in that they cause the instruction pointer to jump to another location. Unlike break, the location may be another layer of the program stack. Unhandled exceptions cause Ruby programs to stop.

When to handle an exception

A simple rule for handling exceptions is to handle only those exceptions you can do something about. That’s easy to say, but sometimes difficult to get right. We have a tendency to want to rescue every exception that could possibly occur. Because we often don’t know what to do about an exception, we tend to just log a message and continue execution. Often this leads to writing extra code to deal with the failures—code we don’t actually need.

We should handle exceptions only when we can reasonably take some action to correct the error and allow our program to continue functioning.

We need to think about three basic categories of exceptional behavior when writing code: possible, probable, and inevitable.

Possible exceptions

Possible exceptions are theoretically possible, but unlikely to occur in the system. When these kinds of exceptions occur, it’s typically because the system is truly broken. In this case, the situation is irrecoverable, and we shouldn’t try to handle the exceptions.

Probable exceptions

Probable exceptions may reasonably happen during our program’s execution—for example, a REST call failure caused by a DNS issue. These are the issues we can foresee when developing our program, and in some cases, we can see a resolution to these problems. This is where we should focus the bulk of our exception handling attention.

Inevitable exceptions

Inevitable exceptions will happen quite often. A common tendency is to allow these exceptions. A more effective approach is to proactively detect the exceptional condition and branch around it. Exceptions shouldn’t be used for flow control. Wherever possible, if we can predetermine that an operation would create an exceptional condition, we shouldn’t execute the operation.

When exceptions occur

Take a corrective action whenever an exception occurs. That is, exception handling is about civilizing the behavior of our programs. You should not bury the exceptions—begin, rescue, bury are anti-patterns that should be avoided.

That said, sometimes the only thing we can do is report that an exception has occurred. The simplest form of this reporting is to print information to standard error indicating that an exception has occurred, and possibly provide some guidance on how to correct the issue.

More sophisticated systems report issues through logging and APM tools like Retrace. APM tools simplify the process by centralizing the reporting of issues and monitoring as well as quickly identifying ways to improve performance and fix hidden exceptions.

Retrace is starting to support Ruby applications to ensure no errors slip through the cracks as deployments get pushed into production.

How to handle an exception

Ruby’s exception handling mechanism is simple: it places the keyword “rescue” after any code that would probably throw an exception. Ruby does require some form of “begin” to appear before the rescue. The general syntax for the rescue statement is as follows:

begin
    #... process, may raise an exception
rescue =>
    #... error handler
else
    #... executes when no error
ensure
    #... always executed
end

The code between “begin” and “rescue” is where a probable exception might occur. If an exception occurs, the rescue block will execute. You should try to be specific about what exception you’re rescuing because it’s considered a bad practice to capture all exceptions.

Be specific about what you rescue

You should specify what your rescue statement can handle. If your rescue block can handle multiple erroneous conditions, use the most general class name possible. In some cases, this is StandardError, but often it’s a subtree of the class hierarchy under StandardError.

A bare rescue will capture StandardError and all of its subtypes—that is, it’ll catch any class raised that extends StandardError. This is problematic. You should rescue only those exceptions you can actually do something about. Other exceptions should be allowed to flow past your rescue statement.

If you’re using an APM tool like Retrace, it will allow you to ignore certain exceptions that you can’t fix and are just creating unwanted noise.

Multiple rescues

In cases where multiple rescues are possible and the rescue operation is different for each, you can specify multiple rescue blocks. An example might be something like this:

3.0.0 :001 > values = []
3.0.0 :002 > begin
3.0.0 :003?>     File.readlines('input.txt').each { |line| values <> Float(line) }
3.0.0 :004?> rescue Errno::ENOENT
3.0.0 :005?>     p 'file not found'
3.0.0 :006?> rescue ArgumentError
3.0.0 :007?>     p 'file contains unparsable numbers'
3.0.0 :008?> else
2.5.3 :009?>     print values
3.0.0 :010?> end
[3.0, 4.5, 9.9, 10.0] => nil

In this example, two possible issues may occur. First, the file might not be found. Second, an ArgumentError might occur if the content of input.txt can’t be parsed to a floating-point number. In each case, the rescue operation is different.

Assigning the error to a variable

As mentioned before, each rescued exception can be assigned to a variable. This allows you to inspect the error that occurred. In the following example, all StandardErrors are captured by the rescue, and the exception message is printed:

3.0.0 :013 > begin
3.0.0 :014?>     IO.readlines('input.txt').each { |line| values << Float(line) } 3.0.0 :015?> rescue => error
3.0.0 :016?>     p error.message
3.0.0 :017?> end
"invalid value for Float(): "fooie\n""

Don’t rescue all exceptions

You can force Ruby to capture all possible exceptions (except fatal exceptions, which are not rescuable) by specifying the class name “exception” in the rescue. However, you never want to do this. Exceptions outside of the StandardError hierarchy are used in the general function of the Ruby environment. By catching them, you can break your program in weird and unexpected ways. Consider the following example:

3.0.0 :001 > points_scored = 100.0
3.0.0 :002 > points_possible = nil
3.0.0 :003 > begin
3.0.0 :004?>     grade = points_scored / points_possible
3.0.0 :005?> rescue TypeError
3.0.0 :006?>     p "The instructor did not provide a value for points possible"
3.0.0 :007?>     grade = 0.0
3.0.0 :008?> else
3.0.0 :009?>     p "Your grade is #{grade}%"
3.0.0 :010?> ensure
3.0.0 :011 >     p "Grade Report Complete"
3.0.0 :012?> end
"The instructor did not provide a value for points possible"
"Grade Report Complete"
=> 0.0

Statement rescue

The syntax of a statement rescue is as follows:

rescue ...error handler...

This can be useful for dealing with simple issues in which a potential exception may occur. For example:

3.0.0 :001 > points_scored = 100.0
3.0.0 :002 > points_possible = nil
3.0.0 :003 > grade = points_scored / points_possible rescue 0.0
=> 0.0

In this case, it’s possible for the math on line 3 to fail. By using nil here, we cause a TypeError. The rescue block will catch all StandardError exceptions and set the grade to zero. This can be a handy shortcut for dealing with these scenarios. You can even place an entire block of code in the rescue here if there are multiple steps to the correction.

3.0.0 :001 > score = 80.0
3.0.0 :002 > possible_score = nil
3.0.0 :003 > grade = score / possible_score rescue begin
3.0.0 :004?>     print 'math error'
3.0.0 :005?>     0.0
3.0.0 :006?> end
math error => 0.0
3.0.0 :007 > grade
=> 0.0

Rescuing loops

The “rescue” keyword can be applied to loops as well. After all, loops are just statements in Ruby. The syntax for rescue on the various loops looks like this:

while  do
    #... loop body
end rescue ...error handler...

begin
    #... loop body
end while  rescue ...error handler...

until  do
    #... loop body
end rescue ...error handler...

for  in expression do
    #... loop body
end rescue ...error handler...

There are some things to consider when using a rescue on a loop. Specifically, the rescue is executed after the loop terminates.

For example:

3.0.0 :001 > scores = [80.0, 85.0, 90.0, 95.0, 100.0]
3.0.0 :002 > possibles = [100.0, 100.0, 100.0, nil, 100.0]
3.0.0 :003 > grades = []
3.0.0 :004 > for idx in 0..(scores.length-1)
3.0.0 :005?>     grades[idx] = scores[idx] / possibles[idx]
3.0.0 :006?> end rescue grades[idx] = 0.0
3.0.0 :007 > grades
=> [0.8, 0.85, 0.9, 0.0]

Of course, this causes a problem. The last score/possibles pair wasn’t evaluated, which isn’t an ideal solution. Ruby provides a way to retry the block between “begin” and “retry” that can fix this problem.

Using retry

In the following example, we’ll build out a full rescue block and then use that rescue block to correct the error condition. Then we will use “retry” to re-execute starting from the begin block. This will give us an answer for each score.

3.0.0 :001 > scores = [80.0, 85.0, 90.0, 95.0, 100.0]
3.0.0 :002 > possibles = [100.0, 100.0, 100.0, nil, 100.0]
3.0.0 :008 > for idx in 0..(scores.length-1)
3.0.0 :009?>     begin
3.0.0 :010?>         grades[idx] = scores[idx] / possibles[idx]
3.0.0 :011?>     rescue TypeError
3.0.0 :012?>         possibles[idx] = 100.0
3.0.0 :013?>         retry
3.0.0 :014?>     end
3.0.0 :015?> end
=> 0..4
3.0.0 :016 > grades
=> [0.8, 0.85, 0.9, 0.95, 1.0]

Using next

Although next isn’t actually part of the rescue mechanism, we can make the previous example less presumptive. A TypeError is raised when no “possibles” value exists in the previous example. We’re setting a value in possibles and retrying the math. This is fine if we understand that the correct value of the possibles is 100.0 for any given evaluation. If that’s not appropriate, we can use a sentinel value to indicate that a computation error occurred and use “next” to cause the loop to proceed to the next evaluation.

3.0.0 :001 > scores = [80.0,85.0,90.0,95.0,100.0]
3.0.0 :002 > possibles = [80.0,110.0,200.0,nil,100.0]
3.0.0 :003 > grades=[]
3.0.0 :004 > for idx in 0..(scores.length-1)
3.0.0 :005?>     begin
3.0.0 :006?>         grades[idx] = scores[idx] / possibles[idx]
3.0.0 :007?>     rescue TypeError
3.0.0 :008?>         grades[idx] = 'Computation Error'
3.0.0 :009?>         next
3.0.0 :010?>     end
3.0.0 :011?> end
3.0.0 :012 > grades
=> [1.0, 0.7727272727272727, 0.45, "Computation Error", 1.0]

Rescue each

You may be wondering if you can use “rescue” with an “each” iterator. The answer is yes. The syntax is as follows:

.each {} rescue ...error handler...

For example:

3.0.0 :001 > values = [1,2,3,0]
3.0.0 :002 > results = []
3.0.0 :003 > values.each { |value| results <<; value / value } rescue results <;< 'undefined' 2.5.3 :004 > results
=> [1, 1, 1, "undefined"]

For a deeper understanding on how to handle exceptions in Ruby refer to the official Ruby Exception Handling documentation.

Conclusion

The rescue block in Ruby is very powerful. It’s vastly easier to use than error codes. Rescue lets you create more robust solutions by providing a simple way to deal with common errors that might occur in your program. At a minimum, you can provide a graceful shutdown and reporting of problems in your code. If you’re looking for something more robust, check out Retrace for Ruby.

]]>
Install Ruby on Your Mac: Everything You Need to Get Going https://stackify.com/install-ruby-on-your-mac-everything-you-need-to-get-going/ Thu, 07 Sep 2023 10:08:47 +0000 https://stackify.com/?p=25058 In this post, we’re going to show you how to install Ruby on your Mac. Along the way, we’ll learn about the steps involved and various bits of knowledge required to get up and going. So if you’re totally new, don’t worry! I’ll list each step and follow it with an “extra credit” section where I’ll explain that step in depth. If you’ve done this sort of thing before and just need some directions, I’ve included a TLDR section showing what commands to run.

Before We Start…What is Ruby?

Ruby is an open-source programming language with a strong developer focus. Created in 1996 by Yukihiro Matsumoto, Ruby became really popular in the late 2000s with the introduction of the Ruby on Rails web framework. While Ruby is used quite frequently for web development, it’s also popular as a scripting language.

Ruby is known for being easy to learn and fun to use. So let’s find out how easy it is to get up and running!

What We’re Going to Do

  1. Open up the terminal
  2. Install a package manager
  3. Use the package manager to install Ruby
  4. Update our PATH
  5. Write and run our first Ruby program

What You’ll Need

  • An internet connection
  • Administrator privileges (you should have this if you’re working on a personal device)
  • 15 minutes (or just a few if you only need the commands)

TLDR—Run These Commands From the Terminal

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
brew install ruby
echo 'export PATH="/usr/local/opt/ruby/bin:$PATH"' >> ~/.bash_profile
source ~/.bash_profile

Step 1: Open up the Terminal

The terminal application on macOS is an operating system command line interface (CLI) that comes installed on new Macs. You can quickly open the terminal by doing the following:

  • Type ⌘+space bar. This brings up the macOS spotlight search, a search utility for opening apps on your Mac.
  • Type terminal into the spotlight search.
  • Press Enter.

Extra Credit for Step 1

When you open a terminal (assuming zero configuration), you start at your home directory. Did you know that a version of Ruby comes installed on your Mac by default?

We can see that by typing some commands into our terminal. The which command allows us to see where on the computer an executable file lives.

which ruby

We passed Ruby as an argument, so the command is finding the Ruby executable location. If Ruby isn’t installed or available to us, the which command will let us know it couldn’t find Ruby.

Now let’s see which version of Ruby we have installed by typing in the following command:

ruby -v

Here, we’re invoking the Ruby CLI and passing the option -v to it. The -v option tells the Ruby CLI to return the version of the Ruby installation to us.

For Mac M1, it returns the following:

ruby 2.6.10p210 (2022-04-12 revision 67958) [universal.arm64e-darwin22]

That means M1 Macs come with Ruby version 2.6 installed.

If you don’t need the latest and greatest Ruby version, you could stop here. But as good software engineers and system administrators, we like to stay on top of things and install the updated versions when we can. Let’s do that by installing a package manager.

Step 2: Install a Package Manager

Hold on! What’s a package manager? A package manager is an application whose job is to manage software on your computer. In this case, managing means installing, updating, and removing software as needed. Package managers will install software in a consistent manner and keep your computer tidy.

As it turns out, macOS has an awesome package manager called Homebrew. Ironically, Homebrew is written in Ruby! Let’s get that installed.

The Homebrew homepage has the install information. We’re going to follow that by running this command in our terminal that we opened in step 1:

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

This command is going to install Homebrew for us. The cool thing about the Homebrew install script is that it will tell you what it’s going to do and prompt you for a yes or no before proceeding. The install script is very informative. One of the important things it points out for us will be that the install script is going to create some subdirectories in the /bin/ directory. More on that later.

Extra Credit for Step 2

Whoa! What’s that install command doing anyway? I’m a big proponent of understanding commands that you paste into your terminal before you run them. The terminal is a really cool and powerful program, but we can harm our machine if we paste someone’s malicious code in there, so it’s important to understand what we’re doing.

I look at this command and see a few notable things:

  • /bin/bash -c
  • curl -fsSL
  • curl is getting content from this address: https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh
  • The output of the curl command is interpolated for the Ruby command

Let’s Explore What Each of These Mean

The /bin/bash portion of the command is giving our terminal a specific location to an executable using the bash command. If you recall from our earlier step, when we used which ruby, we found that the Ruby command was coming from the location /usr/bin/ruby in our bin directory. On Unix-like operating systems such as macOS, /usr/bin/ is where the operating system installs distribution executable files. Distribution executable files are executable files that come with and are managed by your operating system.

I also notice that the Ruby command is getting called with the -c flag. If we type man ruby into our terminal, we can explore the documentation and find out what the -c flag does.

If we scroll down the man page to get to the -c flag, we’ll see that it says, “

Causes Ruby to check the syntax of the script and exit

                    without executing. If there are no syntax errors, Ruby

                    will print “Syntax OK” to the standard output.

” To get out of the man page, just hit q.

As the documentation suggests, the above command simply checks the syntax of the Ruby script and prints a standard output “Syntax Ok” if the syntax is correct.

The curl command

Alright. Now let’s look at the curl command. The curl command is actually cURL, which stands for “client URL.” The Homebrew install script uses curl to fetch data from GitHub.  The command is also using several flags. Again, we can use the man command and pass curl to it…which, while being slightly funny, is also super useful and can help us find out what these flags are doing. So here’s the condensed version of what we need to find in man curl.

  • -f means fail silently on server errors. This is to prevent seeing a text representation of an HTML server error document
  • -s means use silent mode. Silent mode doesn’t show the progress meter or error messages.
  • -S means to show an error message if curl fails. It’s used to modify the -s option to still be silent unless the curl command fails.
  • -L is the location flag. This is a convenience flag to handle redirect HTTP response codes. If the document has moved and there’s a response indicating its new location, curl will go and try to fetch it at that location.

Cool. That was pretty straightforward. We’re fetching data with some flags that modify the way curl outputs status messages.

Fetching raw content from GitHub

If you actually paste the URL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh into your browser, you’ll see that it brings up a Ruby script file. This is GitHub’s site that hosts raw files that are stored in a GitHub repository. It’s useful for fetching just the content of a script.

Interpolation, a fancy word for fancy folks

Oxford defines interpolation as “the insertion of something of a different nature into something else.” In our case, we’re doing string interpolation in Bash. We’re taking the output of one command and treating it like string input. In Bash, the best way to do string interpolation is to call a command from within a set of parenthesis preceded by a dollar sign. So since we’re wrapping the curl command in the parenthesis, like this…

$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)

…we’re treating the output like a string to the Ruby command.

Putting it all together

Ironically, we’re using Ruby to install the package manager, which we’ll use to install a newer version of Ruby!

  1. We’re calling the Ruby command and telling it to execute the content we’re passing to it instead of looking for a file.
  2. We’re pulling a raw Ruby script from https://raw.githubusercontent.com/Homebrew/install/master/install. And we’re doing it without any extra output from curl by passing those command line options. This is smart because the Ruby command wouldn’t know how to interpret any output from curl.
  3. We’re interpolating that script as input to the Ruby command!

Wow. There’s a lot to understand, even about relatively small commands! What I hope you take away from this section is that taking the time to understand some of the extra stuff is important and that the man command is your friend.

Now that we understand this step better, let’s actually install the latest version of Ruby.

Step 3: Use the Package Manager to Install Ruby

Alright, so now that Homebrew is installed, we can use it to install a newer version of Ruby. The command is pretty straightforward:

brew install ruby

With this, Homebrew will go out and fetch not only Ruby but also any dependencies Ruby needs to run. On my machine, for example, Homebrew installed LibYAML prior to installing Ruby.

We’re almost ready to write our first Ruby program!

Extra Credit for Step 3

You’ll notice right now that if you run the ruby -v command again, it’s the same version of Ruby that we saw in step 1. What gives?

Homebrew was nice enough to tell us what happened. Here is a snippet of the output from the brew install ruby command:

ruby is keg-only, which means it was not symlinked into /opt/homebrew, because macOS already provides this software and installing another version in parallel can cause all kinds of trouble.

If you need to have Ruby first in your PATH run:

echo 'export PATH="/opt/homebrew/opt/ruby/bin:$PATH"' >> ~/.zshrc
A brief look at how Homebrew installs programs

Remember earlier when I mentioned that package managers like Homebrew keep our machine tidy by installing things in a consistent manner? This output relates to that bit of information. When Homebrew installs a package, it will actually install it in a directory that Homebrew owns.

We mentioned that /usr/bin is for the distribution of executable files. There’s another directory, /usr/local/bin, that was created by Homebrew in step 2. Homebrew actually makes a directory named “Cellar” inside this directory. Homebrew will install packages into the Cellar and then make symlinks from those packages into /usr/local/bin that are available to us. A symlink, or symbolic link, is a special type of file that acts as a redirect to where the actual file lives. This allows Homebrew to be selective about what executables it makes available.

What does that mean for us?

It means that the newer version of Ruby is installed, but Homebrew isn’t going to put it on the PATH for us. It’s not going to do this because of the existing version of Ruby living in /usr/bin. It tells us how to fix this situation by modifying our PATH.

I’ve mentioned the PATH a lot, and we’re going to talk about it next!

Step 4: Update our PATH

The simplest way to do this is to follow the instructions Homebrew gives us. Run this command:

echo 'export PATH="/opt/homebrew/opt/ruby/bin:$PATH"' >> ~/.zshrc

This will update our Bash profile but not our current environment.

You could open a new terminal at this point, but a simpler method to update your environment is to run this command:

source ~/.zshrc

The version of Ruby that is going to take precedence in the terminal is now the version we installed with Homebrew!

Verify that the new version is installed by again checking the version. It should be a more recent version than what was installed on the system by default.

ruby -v

And now you’ll see the newer version of Ruby returned by the above command that you just installed:

ruby 3.2.2 (2023-03-30 revision e51014f9c0) [arm64-darwin22]

Extra Credit for Step 4

There are some more interesting tidbits to unpack here.

  • PATH
  • echo and >>
  • ~/.zshrc
  • source
The PATH variable

PATH is an environment variable. An environment variable is a piece of data that is available for both us and other subprocesses to use every time we open a shell prompt. The PATH contains a list of directories, separated by colons. When you type a command into your shell, it will look for executable files in those directories, in the order they listed.

The PATH variable serves a couple of purposes. One purpose is to provide a single place to refer to and update an executable’s location. Also, the PATH makes our life easier by eliminating the need to refer to executables by their exact location. For example, if we had not followed step 4, we could still access the version of Ruby we installed, but it would be slightly annoying. If we wanted to check our newly installed Ruby version, we would have to refer to the command like this:

/usr/local/opt/ruby/bin/ruby -v

Now imagine typing that in everywhere! It’s not great, and it could also lead to a mess. If you decided to move that executable to another location, you’d have to type in that new location to reference the command. This would be a nightmare if scripts were using the absolute location. They would all break.

You can update your PATH by appending or prepending a directory to it. That’s what this section of the command is doing. It’s prepending a directory to the existing PATH variable.

export PATH=”/opt/homebrew/opt/ruby/bin:$PATH

Echo and the >> operator

The echo command simply returns whatever we type in the shell back to us. For instance, you can run a command to print “Hello World” in the terminal:

echo "Hello World"
Hello World

The redirect operator used in conjunction with echo is a handy way to modify a file’s contents without opening the file. The >> operator tells the shell to append the output of the previous command to a given file.

This is what we’re doing. We’re appending export PATH=”/usr/local/opt/ruby/bin:$PATH” to the end of our Bash profile.

The ZSHRC file

The ~/.zshrc is a special file that’s sourced when a new shell environment is created. The tilde at the start of that file is a directory alias for your home directory. For our purposes, you can think of this file as a place where you store user preferences when you create a new shell environment. This means that any time you open up the terminal program, anything you place in this file will run first. In this case, the PATH environment variable will be updated to prioritize the directory containing our version of Ruby.

Source

The source command takes a file and updates the current shell’s environment to contain any changes or additions in the sourced file. While our shell would source the Bash profile automatically when a new terminal is created, we can do it manually by running the source command ourselves.

Step 5: Write and Run Our First Ruby Program

We’ve now installed Ruby!  Let’s celebrate by running the ceremonial and obligatory “Hello World” program. We’re going to use Vim, a commonly used editor for Ruby developers. Let’s open a file with Vim.

vim hello_world.rb

Now you have to type the character i to go into “insert” mode. Then go ahead and type the following:

puts "hello world"

Now let’s save and quit. Hit the Escape key, then type :wq and hit Enter.

Celebrate and type

ruby hello_world.rb

And that’s it!

There’s no extra credit here. We’ve already covered quite a bit of content. We set out to install Ruby, and along the way, we learned a little bit about several things:

  • Terminal
  • Package management
  • Shell commands
  • PATH
  • How to exit Vim ?
  • And more!

If you’re planning on using Ruby to write a cool business app, take a look at Retrace. Retrace can do all sorts of things for you, including helping you understand your application’s performance.

Try Stackify’s free code profiler, Prefix, to write better code on your workstation. Prefix works with .NET, Java, PHP, Node.js, Ruby, and Python.

Start Free Trial
]]>
Popular Ruby Libraries https://stackify.com/popular-ruby-libraries/ Mon, 10 Feb 2020 15:23:05 +0000 https://stackify.com/?p=27674 Ruby on Rails Gems is a package manager containing libraries, software packages, and utilities for standard format distribution of  Ruby programs and libraries. RoR Gems have functionality with related files to help save time in web development.

Debugging

Byebug:

Byebug is an effective solution for debugging. This gem takes time between tasks and implementing code by changing variables to perform the robust debugging function.

How to install Byebug:

If you use bundler:

The Usage of Byebug:

Add byebug to initiate debugging. Here is an example of how to add byebug to your code to debug rails:

The rail server initiates:

After this, you will receive a debugging prompt.

Bettor_errors:

This gem shows errors in the web page or website to help users with information. Better_errors is an advanced gem that replaces the Rail error page. Use this gem as Rack middleware in Rack application. 

How to install Bettor_errors:

Binding_of_caller is mandatory for Better Errors’ advance feature, i.e., REPL, local/instance variable inspection, stack frame names.

Tip:  Set config.consider_all_requests_local = true in config/environments/development.rb. If the version 0.5.0 or older, follow the above step.

Search

ElasticSearch:

ElasticSearch is an application integration for helping users search instead of scrolling. 

How to use ElasticSearch for Ruby on Rails applications:

The above gems require bundle install to run the application. 

Admin Panels

Administrate:

Create an admin dashboard with the help of Administrate RubyGems.

How to install Administrate:

This new gem supports Rail from 4.2 and up to 5.0 and above. 

The installer includes an application dashboard.

After, restart your server and visit http://localhost:3000/admin

Activeadmin:

The only framework for building admin panels for Ruby on rails. There are plugins for an  administrative style interface. The gem comes with distinctive features to simplify tasks for the developers.

How to install Activeadmin:

Add the following to your Gemfile:

Run the installer after updating your bundle:

Migrate the database and start the server:

Uploading Files

Minimagick:

RMagic was the traditional library before Minimagick. The command line-option of ImageMagick is available for building the “uploading file” feature.

How to install Minimagick:

You can add the following gem to your gem file to initiate the installation process:

Carrierwave

The new option for uploading and processing files in Sinatra, Ruby and other Ruby web frameworks. Use Carrierwave to add, remove, and upload versions from remote locations. Carrierwave works with S3, AWS and fits with fog gem to integrate with cloud servers.

How to install Carrierwave:

Add the latest version

Add to your gem file in rails

Restart the server. 

Tip: For Ruby 4, use 1times. This gem requires a 5.0 version and Ruby 2.2 above.

Carrierwave_ backgrounder:

Allows image processing and compressing into the background. It bolsters Delayed Job, Resque, Sideqik, and Queue Classic.

How to install Carrierwave_backgrounder:

Add the following into your Gemfile in Rails:

Running generator will create an initializer in config/initializers

Background Processing 

Sidekiq:

Sidekiq is a simple and efficient tool for running applications in the background and simplifies the background process.

How to install Sidekiq:

Add the above command into your gem file. 

Authentication

Ruby-JWT:

This is considered to be one of the safest data transfer systems between two parties. It is the implementation of RFC 7519OAuth JSON Web Token (JWT).

How to install Ruby-JWT:

Add the above and below gem into gem file:

Run bundle install.

With  security being the utmost priority, artificial intelligence is important. 

  • Devise:  It operates to perform complex security levels – from authorization via email and password to a referral system.
  • Recoverable: Resets user password and sends reset instructions.
  • Trackable: Monitors timestamps, IP addresses, and sign-in accounts.
  • Rememberable: Manages the token generation and clears the user from saved cookies.
  • Confirmable: Sends emails with confirmation instructions and verifies whether the account is signed-in or not.

How to install Devise:

Add the following to gem file:

It works with Devise 4.0 with Rails 4.1. 

Run bundle install and then  the generator:

HTTPClient:

It provides access to web resources via HTTP with MT-Safe design. After setting up an instance, call  through several threads without synchronization:

How to install HTTPClient:

Create a simple client:

Utilize “http_proxy” or “HTTP_PROXY instsead, HTTP proxy.

Curb:

Curb is a Ruby language that binds the client-side URL transfer library. You can install Curb into Gem file:

If you are using Windows, make sure you use the DevKit and development version of libcurl. Unzip and run in your command line.

Net::HTTP:

This can be used to build net:: HTTP user-agents. Below is the example of request types using persistent connections:

: start creates a connection to the HTTP server kept open for the duration of the block. There are request types Net:: HTTP described below:

Here is the request class:

  • Net::HTTP::GET
  • Net::HTTP::HEAD
  • Net::HTTP::POST
  • Net::HTTP::PATCH
  • Net::HTTP::PUT
  • Net::HTTP::PRO PATCH

HttpRb:

It is used for making requests from Ruby. The method is used for chaining system to build requests, similar to Python’s request. Http.rb uses http_paser.RB to parse native extensions based on node.js parser and Java port.

How to install HttpRb:

Add below line to app’s gem file:

Then executes, 

Or you can install by yourself as

Inside of your Ruby Programs do

Testing

Capybara:

A test framework for web applications, running with RSpec. The gem is responsible for the user’s prompt action and suggests various methods of tests and debugging.

How to install:

It requires Ruby 2.4.0 and above version. And to install, add it to gem file and run bundle install

Add below line to help test helper file:

If the application is not a Ruby app and a rack app,set Capybara.app to your Rack app:

Using Javascript or remote URL requires a different driver. If using Rails 5.0 and above and not using the Rails system test from 5.1, swap the ‘server’ to launch the app in Puma to match Rails result:

Monitoring Ruby Applications:

Troubleshooting problems with your Ruby application can be very difficult without the proper tools. Implementing an Application Performance Management tool into your environment can help you easily pinpoint and optimize your Ruby Application. Stackify’s APM tool, Retrace, makes it easy to find slow web requests, slow database queries, application errors, and view your application logging.

]]>
How to configure HTTPS for Ruby on Rails (RoR) https://stackify.com/how-to-configure-https-for-ruby-on-rails-ror/ Thu, 06 Feb 2020 15:23:39 +0000 https://stackify.com/?p=27669 RoR (Ruby on Rails) is a server-side web application framework. To make it more secure, use HTTPS instead of HTTP. 

Step One: Buy an SSL certificate:

First step is purchasing  an SSL certificate. There are various  types of SSL certificates, based on your requirements including: 

  • Extended Validation Certificates (EV SSL)
  • Organization Validated Certificates (OV SSL)
  • Domain Validated Certificates (DV SSL)
  • Wildcard SSL Certificate
  • Multi-Domain SSL Certificate (MDC)
  • Unified Communications Certificate (UCC)

The most popular ones are the DV SSL, EV SSL, and OV SSL. While the most expensive, the EV SSL is my favorite as it displays information like country of origin, the business name, padlock, and the HTTPS when linked to your web server. The green font is unique to EV SSL and a symbol of trust.

(image)

However, if you are concerned about unlimited subdomains, the wildcard SSL certificate is an ideal option for single protection for subdomains.

DV SSL doesn’t involve high-level validation and is easy to set up. It is also one of the most inexpensive, so if you don’t want to use a free SSL certificate, this one’s for you.

Regardless of which SSL certificate you purchase, the CA (Certificate Authority) will email you your SSL certificate and CA file bundle.  

Step Two: Enable web server to use HTTPS:

Now that you’ve purchased your SSL certificate, enable the web server to use HTTPS using the configuration  files from your CA.

For better understanding, let’s name the SSL certificate as ‘certificate’ and the private key as ‘private key.’ 

Depending on web server requirements, upload the CA bundle file and SSL certificate together.

The CA bundle is a chronological collection of SSL certificates needed. It can be from the most specific generated to the root file or the other way around.

The use of the root certificate is generally limited and usually omitted.

Now, let’s consider a scenario where the bundle contains the SSL certificate.  In that case, it is likely to appear at the top of the list.

(image)

You can choose to concatenate or link all these steps together or  using the ‘cat’ unix utility.

Once you’ve  fixed  the HTTP and shifted  it to HTTPS enabled , you can run RoR application on HTTPS.

After setting the value to ‘true,’ the configuration flag  ‘force_ssl’ can force the application to run under HTTPS. If you want to run the certificate flag on all environments, that involves a simple bit of code.

(image)

(image)

The current version 6.0 provides personalization. When extending the flag across the entire environment, all actions will run on HTTPS.

And here’s how it works: 

  • All Cookies are  flagged as secure
  • You will get the response with HTTP (HSTS) Strict Transport Security header. The HSTS redirects all the requests to HTTPS only
  • All the requests will be directed to HTTPS right away

It’s not advisable to use RoR below version 3.1, but for those who do, use rack-SSL. When compared to ‘force_ssl,’ it is more flexible. Using the ‘:exclude’ command, you can choose to use either HTTPS or HTTP on a case-by-case basis. It is  great option to run the same program on HTTP and HTTPS simultaneously to identify, locate, and fix the respective problems if any. 

However, based on security concerns, it is better to use HTTPS instead of HTTP. It increases the complexity of the controllers and limits the use of extraneous security measures like headers. Today, most providers are now distributing their resources evenly between HTTP and HTTPS.

Step Three: Monitor the performance of your RoR application

Troubleshooting issues within your RoR application can be difficult and time consuming without the proper tools.  Ensure the performance of your RoR application by using an Application Performance Management tool.  Stackify’s APM tool, Retrace, efficiently finds slow web requests, database queries, and application errors while giving you insight into your application logs.

]]>
A Look At 5 of the Most Popular Programming Languages of 2019 https://stackify.com/popular-programming-languages-2018/ Fri, 30 Aug 2019 13:02:57 +0000 https://stackify.com/?p=14766 If you’re a software developer, then you probably—every now and then—feel overwhelmed by the super-fast pace at which our industry evolves, and that’s fine. I certainly feel that way sometimes, especially when trying to keep up with the latest trends.

But it’s possible to be well-informed about what’s going on out there, and use that information to your advantage, by being economical about your learning.

Sure, there are lots of programming languages. Sure, new ones keep being created every week—and don’t even get me started on JavaScript frameworks.

Do you need to learn all of them? Of course not.

First, learn about a number of the most popular programming languages. Then, narrow that list down, by picking the ones that make the most sense for your current knowledge level, employment status and other criteria that might make sense for your scenario.

For instance, if you intend to learn the functional paradigm, then pick a functional language from the list. Rinse and repeat.

That’s what this post is about. We’ve done the legwork for you, compiling a list of five of the most popular programming languages for 2019. Now you only have to read it and put it to good use.

A Look At Our Sources

You might be wondering where have we found our data for this post. There are hundreds of metrics to look at when considering the top programming languages, but we focused on a few of the most authoritative, namely Tiobe and GitHub.

Tiobe Programming Index

For decades, Tiobe (the software quality company) has generated an index of the most popular programming languages. They update this list monthly, pulling in data from hundreds of sources around the world.

For more on how the Tiobe Index is calculated, see here.

GitHub

GitHub is one of the largest code repositories in use today. Every year they create a Year in Review report, sharing statistics about their programmer community. We use this data as another indicator of language popularity.

In this post, we also attempt to predict the future of programming languages.

We use a wide variety of resources to predict the fastest growing languages and the most influential languages. Of course, all of these insights are up for debate, but they are worth considering if you want to stay ahead of the curve.

Let’s get into it. Below are the most popular programming languages of 2019, and predictions about the future of code.

Most Popular Programming Languages

The table above shows the top 20 most popular programming languages as of August 2019. The Tiobe Index works like market share; the percentage is the amount of “market share” a language holds.

Tiobe factors in variables like the number of professional developers worldwide, training courses, and third-party vendors.

Most of this information comes from analyzing search engine results. Here is an explanation of how the Tiobe Index is produced.

Last, but not least, we take data from The GitHub Year in Review—which is a report published annually by GitHub.

Using the data from GitHub we can see not only the most used languages on the platform during the year, but also the ones which are growing the fastest.

The chart above shows GitHub’s top languages over time.

The Top Programming Languages, Explained

What makes the top programming languages so popular? We’ll take a deeper look at five of the top languages to learn how they’re used and why people love them.

1. Java

According to Tiobe, Java has been the number 1 or 2 most popular language basically since its creation in the mid-90s. Many of the world’s biggest companies use Java to build desktop apps and backend web systems.

If you know Java, chances are you won’t be desperate for work!

There are a number of factors that make Java so popular:

  1. Portability: Thanks to the platform-agnostic Java Virtual Machine (JVM), Java can run on nearly every system. Java is also the most popular Android language, so the vast majority of Android apps are built in Java.
  2. Scalability: James Governor has a saying: “When web companies grow up, they become Java shops”.Java is built for scalability in mind, which is why it is so popular among enterprises and scaling startups (Twitter moved from Ruby to Java for scaling purposes). Since Java is a statically-typed language, it’s faster and easier to maintain with less bugs. It is also backwards compatible, which means old versions of the language will still run perfectly even after new versions are released. This is a big relief for businesses who would otherwise worry about rewriting their code every time a new version comes out.
  3. Large community: The popularity of Java helps to ensure its future popularity, thanks to a huge community of users. With massive Stack Overflow and GitHub communities, developers can find help on virtually any problem they might encounter. Coupled with its portability, developers know that investing in Java will pay dividends for a long, long time.

If you’re a Java developer, check out the Stackify Retrace and Prefix tools so you know exactly what’s going on with your code. If you’re still learning, check out some of the web’s best Java courses here.

2. The C Programming Language

C is one of the oldest, most popular programming languages, thanks to its near universal portability and early adoption by Tech’s biggest brands, including Microsoft, Apple, Linux, and Oracle.

C is also the most popular language for embedded systems in cars, electronics, and other devices.

Nearly everything that we touch today, from our cell phones to alarm clocks, is influenced by—if not directly written in—the C language.

Why is it still a popular programming language to learn today? First, it’s essentially a portable assembly language. It works with nearly every system and operates about as low to the machine as you can get.

C also has features that make is perfectly qualified for operating systems and embedded systems (like your car’s dashboard). Thanks to its relatively small runtime, C is perfect for keeping these systems lean.

Any programmer will benefit from learning the C language.

Many algorithms written and shared online are done in C. It’s essentially the “universal language” of programming languages. C spinoffs like C++ and C# are also among the top 5 most popular languages, again emphasizing the influence C still has today.

3. Python

The popularity of Python has risen steadily over the past 15 years, finally breaking the top 5 on the Tiobe Index a few years ago. This is because Python is a major language in some of the most exciting technologies today.

Machine learning, artificial intelligence (AI), Big Data, and Robotics all rely heavily on Python (Robotics also relies on C for its use in systems programming). Cyber Security, one of the top software challenges of our time, is also driven by Python.

It’s surprising how simple Python is to learn.

It’s now the most popular introductory language taught in universities and often picked up by experienced developers as a second or third language.

4. JavaScript

Thanks to the ubiquity of web browsers, JavaScript has become one of the most popular programming languages in the world, and number 1 on GitHub in terms of pull requests.

There are notable complaints with JavaScript (more on that in a bit), but JavaScript has held its own against newer languages and will continue to play a significant role on the web.

JavaScript allows developers to add interactive effects to web pages. It often works alongside HTML, but it’s becoming more common for web apps to be built entirely in JavaScript.

Because of its simplicity and speed, more startups and tech businesses are starting to use JavaScript on the backend via the Node.js framework.

5. Ruby

Ruby is one of the most popular languages among tech startups.

Many Silicon Valley unicorns have been built on Ruby, including Airbnb, Twitch, GitHub, and Twitter. Its popularity is bolstered (and perhaps dependent) on Ruby on Rails, a full-stack web application framework that runs Ruby.

Ruby is beloved by developers for a number of reasons.

This explains why startups are so fond of the language: it enables the famous startup mantra, “move fast and break things.”

The downside of Ruby is its scalability.

Ruby is a dynamically-typed language, which makes it very flexible and great for prototypes, but difficult to maintain at scale. As a Ruby app grows, the dynamic nature of the language obscures the source of code errors and eats up computing resources. This is why Twitter switched from Ruby to Java.

Twitter Headquarters Building
“Twitter was originally built using Ruby, but switched to Java so they could scale more easily”. Photo by Aaron Durand

2020 Programming Language Predictions

Now that we’ve looked at the most popular programming languages right now, we’re going to take the liberty of predicting what’s to come in 2020 and beyond.

Based on trends from previous years, we’re confident that the list of top programming languages won’t change that much from year-to-year.

But where are the winds headed? Let’s try to take a glimpse into the future.

Fastest-Growing Languages

Every year, the Tiobe Index crowns the fastest growing language as “Language of the Year”. Recent winners have been Python (2018), C (2017), Go (2016), Java (2015), and JavaScript (2014).

Tiobe will crown a new Language of the Year in the next few weeks, but their website says the candidates are Kotlin and C. It’s an interesting dichotomy with C being of the oldest languages (1987) and Kotlin being one of the newest (2011).

Let’s look at each language.

Kotlin

The couple last years have been great for Kotlin, the statically-typed programming language from JetBrains.

On top of receiving loads of good press, in 2017 Kotlin was also named an official development language for the Android platform.

This is an enormous boost; not only is Android the most popular mobile development platform, but it’s also the 3rd most popular development platform behind Windows desktop and Linux, according to StackOverflow.

And, as you can see in the image above, GitHub’s report indicates that Kotlin was the fastest growing language in 2018.

There are several reasons for Kotlin’s rise in popularity, not least of which is its 100-percent interoperability with Java and the fact that IT runs on Java Virtual Machine (Java is another official Android language).

Kotlin also compiles down into JavaScript, making it extremely versatile for both front and back-end development.

Expect to hear a lot more about Kotlin in the years to come, and if possible, take some time to add it to your repertoire (it’s surprisingly simple).

The C Programming Language

We’ve already discussed why C practically runs the world, but what’s behind this latest boost in popularity?

Like we mentioned earlier, C is the perfect language for embedded systems, and frankly, everything is becoming an embedded system these days.

C is one of the top programming languages for IoT devices, including wearables and car dashboards. As more products become “smart”, we’ll see C’s use continue to expand.

[adinserter block=”33″]

Most Influential Programming Languages

The popularity of a programming language is one thing, but which languages will have the greatest influence in the years to come?

One way to determine whether a language is “influential” is to look at the technologies built on top of it (see Python and C).

Another way is to look at a language’s ability to solve intrinsic software problems. For the sake of treading new ground, let’s focus on the latter definition.

I turned to Jake Ehrlich, a software engineer and programming language enthusiast, for his thoughts on the most influential programming languages.

“Individual problems tend to be more influential than any one specific language,” said Ehrlich. “Right now the biggest problem we’re facing is end of Moore’s law.

Moore’s Law says that computing power will double every 18 months, and for the first time in decades, computer chip makers are not keeping pace. That means software developers need to figure out a way to make powerful web applications with the same amount of computing processing power.

Another hardware issue Ehrlich references is power consumption.

“Batteries just aren’t getting better,” said Ehrlich, despite the fact that more and more of our devices run on them. “So now we need to make hardware and software that is as power-efficient as possible.”

One solution to both of these challenges, Ehrlich suggests, is the use of native languages. “It turns out that the same sort of features that improve speed and responsiveness also allow us to write more power-efficient code.”

Ehrlich thinks we will see a move towards native languages like Go, Swift, Rust as hardware attempts to catch up.

Learn the Most Popular Programming Languages

The world’s biggest challenges and opportunities are driven by programming languages discussed in this article.

While this post is all about the code, it is really an ode to the people who create that code day-in and day-out. From machine learning to cybersecurity and web apps to battery power, these technologies will only go as far as software developers take them.

Try Stackify’s free code profiler, Prefix, to write better code on your workstation. Prefix works with .NET, Java, PHP, Node.js, Ruby, and Python.

Want to learn more about the most popular languages? Here are a few resources to get you started:

Java

C

C++

Python

C#

JavaScript

]]>
Rails Geocoder: A Guide to Managing Locations in Your Apps https://stackify.com/rails-geocoder-a-guide-to-managing-locations-in-your-apps/ Thu, 27 Jun 2019 10:20:37 +0000 https://stackify.com/?p=25519 The introduction of Google Maps in 2005 changed the way we think about the internet. It’s hard to remember now, but there was a time where the internet was disconnected from the physical world. You might find a business’s website, and if you were lucky, they’d have an address included. A national chain of restaurants or grocery stores probably wouldn’t be able to tell you their nearest location to your home.

All of that has changed, today. Now, it’s expected that your website not only know where all your business’s locations are, but where your users are located, too. Thankfully, in 2019 there are a myriad of options for mapping and geolocation services that help developers add those features to websites. Today we’ll take a look at Rails geocoder.

The Ruby on Rails Geocoder Gem

For developers writing Ruby, the geocoder gem provides a one-stop shop to finding your way around those services. It integrates with a dizzying list of service options as well as working seamlessly with data store options like Mongo and PostGIS. Thankfully, plugging it into your app is simple. Simply add the gem to your gemfile, install the gem with bundler, and you’re off to the races.

Integrating the geocoder gem into Rails itself isn’t entirely seamless. You’ll need to do some manual setup to generate models and forms to store data about the locations you’ll be geocoding. That’s okay! You’ll have full flexibility to approach geocoding exactly as you like.

What’s more, geocoder itself isn’t tied to Rails. You can use it in other software projects with the same installation steps. By decoupling itself from Rails, geocoder is able to suit a broader variety of applications out of the box.

Choosing a Geocoding library

Once you’ve installed Rails geocoder, you’ll have a decision to make about which geocoding API to use. If you’re just making a website for yourself, that decision will probably be pretty easy. You’ll probably want to use the Google Geocoding API. Google geocoding comes with a number of free requests per day, and provides gobs of good information. It’s easy to sign up for a key, and nearly everyone has a Google account for some purpose these days. That’s all you need to sign up.

If you’re working for a business or professional site, you might need to do a bit more research ahead of time. Google provides terrific professional plans, but you might also want to check out Bing Maps or potentially MapQuest. Be sure to work with your employer to determine if you already have a license for one service or another. There are dozens of options, so pick what works best for you and your company.

The good news is that all those services are directly integrated into the geocoder gem. You’ll work with the gem the same way no matter which API you choose. That’s convenient; it means that if you ever need to switch providers, all you’ll need to do is edit some config files.

Integrating with a database system

If you’re bootstrapping an application, you should make sure that your database will work with geocoder. There are two primary databases on the market today for geospatial work. The first is PostGIS, an add-on for PostgreSQL. PostGIS provides a terrific API for querying geospatial data within a relational database paradigm. It’s easy to store latitude and longitude values in a PostgreSQL database, then query them using the PostGIS library. This works natively within the geocoder app.

The second primary database you’ll run into is MongoDB’s geospatial library. Much like PostGIS, this is a first-class system for working with geospatial data in MongoDB. Unlike PostgreSQL, MongoDB is not a relational database. It’s known as a NoSQL database.

If you’re building an application using the geocoder gem, you’ll probably want to use one of those two databases. Geocoder also supports MySQL, but my experience is that MySQL’s geospatial features are a bit slower to use than PostGIS. Geocoder supports SQLite, but SQLite is not a production-level database, and you should only use it for testing.

Finally, there are other databases which do provide geospatial capabilities, like MsSQL. Unfortunately, at the time of publication, Rails geocoder doesn’t support Microsoft  SQL Server, so you should avoid using it for this application.

Integrating Geocoder into your app

To imagine integrating geocoder into your app, let’s consider a practical example. I’m lucky enough that I work from home in my day job, in exurban West Michigan. I love not having a commute, but I do miss being able to grab a quick lunch with a friend during the work week. I still make regular plans to visit with friends and find lunch, but it can be difficult knowing where to go. Often times, we’re 30-40 minutes by car away from one another. Neither one of us wanting to drive too far means we’ve got to try to find something in between our current locations.

This would be a great use for the geocoder gem. We could easily code up an application that would find the median point between our two locations, and feed us back a list of restaurants that are near that midpoint. This isn’t a coding tutorial post, but let’s walk through the geocoder gem API quickly and we can see just how easy this would be.

Using Geocoder to find things near a midpoint

The first thing we’d need to do is collect the addresses for each person. In my personal usage, I’d only ever use two, but the function you need from geocoder actually supports a list of locations. You could build a quick Rails form or CLI program to collect a list of addresses from a user. Once you have those, you’d need to run each address through the Geocoder.search function. That will return information about the address you chose, including the latitude and longitude. You’ll want to save those.

Once you have the latitude and longitude for all points, you can use that data to calculate the central point between them. This is once again, a pretty simple function call. You’ll want the Geocoder::Calculations.geographic_center function. This will provide you another latitude and longitude. It’s the one that lies at the geographic center of the points that you provided.

Once you have the central point of the group, finding nearby items is academic. In my experience, the best way to do that is to use the Google Places API, and for example search for “restaurants” near your central latitude and longitude. Maybe, if you’re feeling fancy, you can add an option to provide a search term as well—for those days when you want to search for “steakhouse” instead.

A quick note on Geocoding APIs: sometimes, they can be a little flaky. My experience is that your code might work fine for weeks, then suddenly have a day where everything is broken. All this despite the fact that you didn’t change anything at all. If you’re setting up an application on the web that uses geocoding APIs, I’d highly recommend looking into quality application performance monitoring like Stackify Retrace. If things start to break, you really want to know about that, ASAP.

Pinpoint

Making the world your oyster

The time when your application could be ignorant of the Earth around it is long past. The good news is, it’s easier than ever to hook your application up to mapping services. Most of the time, you can add mapping to your application in a day or less. Doing so is almost always low cost, and usually free. Having quick and easy mapping capabilities will drive scores of customers to your business. If you’re someone who’s just tinkering, there are great options too. Things are only limited by your imagination. And if you decide to build a web application that can find restaurants at the midpoint between two locations, drop me a line. I’m always looking for a good place to get lunch.

Start Free Trial
]]>
How Does Ruby Garbage Collection Work? A Simple Tutorial https://stackify.com/how-does-ruby-garbage-collection-work-a-simple-tutorial/ Thu, 20 Jun 2019 19:09:07 +0000 https://stackify.com/?p=25413 Ruby, like most other modern, high-level programming languages, doesn’t force you to manage memory. This feature is called garbage collection, or GC, and you get it for free in Ruby. You can write tons of Ruby code and never give a second thought to the fact that under the covers, Ruby is doing a bang-up job of allocating and freeing memory for your code to use. But it certainly couldn’t hurt to learn something about how Ruby garbage collection works. In particular, there are some settings you can tweak to adjust the Ruby garbage collection algorithm to make it work better for your needs. Read on to learn all about it!

What is garbage collection?

The first misconception we have to clear up is the name. “Garbage collection” is kind of a lie—or at least a limited description. The Ruby garbage collector also allocates memory. It’s a complete memory management system. Most people probably picture the garbage collector as a janitor, picking up after kooky kids and taking out the trash. But the garbage collector is more like the Wizard of Oz, the man behind the curtain working the levers, getting memory from the operating system, keeping track of what’s using it, and freeing it back up when it’s no longer needed. It’s the engine that makes your program work!

Fundamentally, the core of memory management uses the “malloc” and “free” C functions. The first stands for “memory allocation,” and it does just what it says. You call it with the number of bytes of memory to allocate and it gives you a pointer to the starting point in memory for your allocation. It’s up to you to make sure you don’t try to write outside your allocated memory. To give the memory back to the OS when you’re done with it, you call the free function and pass it the pointer that malloc gave you.

There’s also “calloc,” short for “contiguous allocation.” It lets you allocate multiple blocks of memory at once. Then there’s “realloc,” which allows you to reallocate a section of memory you’ve already allocated but change its size. This last function suggests some of the potential difficulties with managing memory: you have to know how much you need, and that can change based on runtime concerns. You also have to be sure to free it up when you’re done with it or you’ll have a memory leak. Isn’t it a good thing Ruby does all this for you?

Garbage collection in Ruby

Early computer guru John McCarthy wrote the first garbage collector way back in 1960 to simplify memory management in the Lisp programming language. It’s pretty amazing that garbage collection has been around that long! This was also a mark-and-sweep garbage collector, which is the same algorithm that Ruby uses for its garbage collection.

Before we get to mark-and-sweep, though, there’s an important reality that you have to understand with Ruby garbage collection: Ruby stops running your program in order to do garbage collection! We call this “stop-the-world” garbage collection. It has to do this to ensure your code won’t attempt to allocate memory while it’s in the middle of figuring out what needs to be cleaned up.

So, if our program stops running every time garbage collection runs, it’s obviously very important that garbage collection is as fast as possible. The big brains behind Ruby have put a lot of effort into tweaking and improving garbage collection performance—making the wizard wiser!

Marking and sweeping

Since everything in Ruby is an object, Ruby garbage collection is all about object management. First, allocating memory takes some time, so Ruby pre-allocates thousands of objects to have them ready when you need them. This is called the “free list.”

Garbage Collection

To free up the memory used by an object, Ruby first has to make sure that the object is no longer needed. It does this in multiple passes. In the “mark” phase, Ruby crawls through all the objects and marks the ones that are still in use. It does this by toggling a flag in a free bitmap. Next comes the “sweep” phase. Ruby goes through all the objects again, cleans up the unmarked objects, and returns them to the free list. It does this by just manipulating pointers, so it’s pretty fast.

Ruby also uses the tri-color mark-and-sweep approach. This divides objects into three categories: white, gray, and black. White objects are unmarked, possibly collectible objects. Gray objects are marked, but may have references to white objects. Finally, black objects have been marked, and definitely don’t point to any white objects. The mark-and-sweep process goes through and marks everything white, then marks objects gray while it’s checking their references, and then marks objects black as it figures out that they have references. Then, during the sweep phase, all the white objects can be swept.

Garbage collection improvements

The creators of Ruby are always trying to make Ruby better. Various versions of Ruby included improvements to the garbage collector. Ruby 2.1 added generational garbage collection. This is based on the theory that most objects are used briefly and then aren’t needed anymore. With generational garbage collection, Ruby maintains separate object spaces for “young” and “old” objects. Then it goes through only the young spaces most of the time. This is the “minor GC” phase.

If an object survives three garbage collections, it’s promoted to the “old” object space. These objects are checked only during a “major GC.” If there isn’t enough space in the young space to create new objects, then Ruby runs garbage collection on the “old space.” This full garbage collection is basically the same as the traditional, pre-2.1 garbage collection. The minor GC takes less time, so the overall time spent in garbage collection is less. Pretty ingenious!

Going incremental

The Ruby core team wasn’t content to rest on their laurels, however. The very next version of Ruby, version 2.2, had another improvement to garbage collection: incremental garbage collection. This approach involves running shorter mark-and-sweep passes more frequently. It means spending the same amount of time in garbage collection overall, but in more frequent and shorter bursts. Since the pauses are shorter, there’s less impact on the program.

Achieving incremental garbage collection in Ruby was pretty hard and complicated. It involved adding the concept of protected and unprotected objects. But, fundamentally, switching to incremental garbage collection meant more frequent but faster garbage collection. Instead of spending something like 100 ms doing a full mark-and-sweep phase, your code might spend 10 ms 10 times.

More improvements

Those big changes in Ruby 2.1 and 2.2 were the most profound improvements to Ruby’s memory management. Since then, there hasn’t been much in the way of changes to the garbage collector. Ruby 2.6 did include some tweaks to the mark-and-sweep process that resulted in lower memory usage.

Ruby 2.7, which should be out this upcoming Christmas, is slated to include “heap compaction” garbage collection. The heap is the section of memory that allocates to programs. As objects are allocated and freed, the space you’re using on the heap can get messy, with gaps of unused space between your objects. If instead you compact the used memory together, then all your objects are together and there’s no wasted space. That will be a nice Christmas present!

Alternative allocation

One way to improve your garbage collection performance is to use an alternative memory allocator. One popular such library is jemalloc, written by Jason Evans. It emphasizes fragmentation avoidance. Another option is TCmalloc, short for “thread-caching malloc.” As you might have guessed, this library has strategies to avoid lock contention for multithreaded code. Using an alternative allocator isn’t a decision you want to make lightly, so you should test it carefully.

Garbage can

Garbage collection configuration

Ruby will check a standard set of environment variables to set certain garbage collection parameters. You don’t have to set these. Previously, the default values weren’t the best for large Ruby on Rails applications, but that’s no longer the case. If you do want to try tweaking them, here are the options, straight from the Ruby C code comments:

  • RUBY_GC_HEAP_INIT_SLOTS: Initial allocation slots.
  • RUBY_GC_HEAP_FREE_SLOTS: Prepare at least this amount of slots after GC. Allocate slots if there aren’t enough slots.
  • RUBY_GC_HEAP_GROWTH_FACTOR: Allocate slots by this factor. (next slots number) = (current slots number) * (this factor)
  • RUBY_GC_HEAP_GROWTH_MAX_SLOTS: The allocation rate is limited to this number of slots.
  • RUBY_GC_HEAP_FREE_SLOTS_MIN_RATIO: Allocate additional pages when the number of free slots is lower than the value (total_slots * (this ratio)).
  • RUBY_GC_HEAP_FREE_SLOTS_GOAL_RATIO: Allocate slots to satisfy this formula: free_slots = total_slots * goal_ratio. In other words, prepare (total_slots * goal_ratio) free slots. If this value is 0.0, then use RUBY_GC_HEAP_GROWTH_FACTOR directly.
  • RUBY_GC_HEAP_FREE_SLOTS_MAX_RATIO: Allow to free pages when the number of free slots is greater than the value (total_slots * (this ratio)).
  • RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR: Do full GC when the number of old objects is more than R * N where R is this factor and N is the number of old objects just after last full GC.

You can run GC.stat in an irb console running your app to get all sorts of garbage collection statistics. Several would be useful for getting numbers for these settings. As long as the variables are set in your OS environment, Ruby will pick them up.

GC.start is another good Ruby garbage collection command to know. It kicks off a garbage collection cycle. If you have a long-running script that’s chewing up memory, you can have it call GC.start periodically to keep the memory usage under control.

Mind your memory!

Garbage collection in Ruby has come a long way since the early days. Once Ruby 2.7 is out and heap compaction is rolled in, Ruby should really scream. If you still need to tweak your application’s garbage collection, do so carefully and with adequate testing. And if you want more insight into what your app is doing, including its memory usage, check out Stackify Retrace. It will give you a wealth of useful information about your app and help you find bugs.

Start Free Trial
]]>
AWS Lambda With Ruby: A Complete Getting Started Guide https://stackify.com/aws-lambda-with-ruby-a-complete-getting-started-guide/ Fri, 14 Jun 2019 14:19:30 +0000 https://stackify.com/?p=25324 It’s five o’clock on a Friday afternoon. There are no new bug reports and everything is looking smooth. Your plan of a relaxing weekend is in sight when you get a call—the website you look after isn’t responding. 

Yikes.

AWS Lambda minimizes the chance of this truly terrifying event from happening by taking care of server maintenance while you focus on coding robust applications.

AWS Lambda is a function-as-a-service platform that stores and executes your code when triggered by an Amazon Web Service (AWS) event. These events range from making an API call, to saving a file, to updating a database. You only pay for the execution of the function. There’s no other associated running costs or server maintenance, and you don’t need to worry about server load, because AWS will handle scaling. That gives you a consistent experience, no matter how much your function is used.

This post introduces AWS Lambda, discusses when you should and shouldn’t use it, and takes an in-depth look at how to create your first Ruby function using the AWS console.

The origins of AWS Lambda

At the 2014 AWS re:Invent conference, Amazon introduced Lambda to the world. Dr. Tim Wagner, general manager of AWS Lambda at the time, explained the benefits of using Lambda over EC2, the popular compute engine. Renting virtual machines in the form of EC2 instances from AWS brings flexibility and choice, but the tradeoff is that there’s an unnecessary cost when idle. Plus, there’s the additional complexity maintaining the infrastructure even when it’s not in use.

The benefits of Lambda

The benefits of AWS Lambda, as explained by Tim Wagner at re:Invent 2014, are

  • Reduced complexity. There’s a fixed operating system, fixed software language, and a fixed version.
  • No infrastructure to manage. AWS owns and manages the infrastructure. You only pay for the time your code runs.
  • Implicit scaling. AWS will handle scaling, no matter how much you use your functions.

An explanation of AWS events

An AWS event is a JSON message containing the origin and associated event information, depending on the service. For example, if you add a file to the Amazon Simple Storage Service (S3), this will create an event containing the origin as the Simple Storage Service, the location of the file, and information that an item was added.

The services that can raise events that can trigger a function are

Events trigger a Lambda function execution

Events trigger a Lambda function to execute. It’s executed either directly or is added to a queue to be executed in the future. If you’d like the full list of how services create events, you can check out the AWS documentation. In short, a Lambda function subscribes to the notification-specific event from a specific source and will ignore all other events from any other source.

Programming language support

AWS Lambda currently supports RubyJava, Go, PowerShell, Node.js, C#, Ruby and Python. AWS also periodically introduces support for new programming languages

Use cases where Lambda excels

Lambda excels when the task has one or more of the following characteristics:

  • It’s isolated. Tasks that perform only one function—for example, updating a database or storing a file—are great.
  • It’s asynchronous. We’re talking about low priority tasks that don’t expect an immediate response. This could be sending an email or SMS.
  • It broadcasts. That means it’s updating lots of different systems from one action, like creating a repository on GitHub.
  • There are big peaks in demand. Lambda works well when, during different times of the year or day, the demand is different. This could occur during peak holiday season.
  • There’s low throughput. This occurs when a task happens rarely, such as a sensor that only reports on change (like a door).
  • It’s a prototype or mock. Lambda shines when you’re working with a proof of concept before committing more time to a project.
  • It’s stateless. Nothing needs to be stored in memory.

Use cases where Lambda is not so useful

Lambda doesn’t excel where the task has the following characteristics:

  • It’s long-running. Functions are limited to 15 minutes, so any tasks that exceed that will fail.
  • It has a consistent load. It may be cheaper to use a dedicated instance if the load is predictable.
  • It’s intensive. Functions can only allocate 3GB of memory, so any intensive tasks will fail.
  • It requires a specific operating system or language. If tasks are tied to a specific operating system and have limited language support, Lambda might not help.
  • It has a stateful system. Here, we’re talking about tasks that rely on a state to be stored between functions—for example, storing and retrieving files locally on the server.

A use case for writing a Lambda function

Imagine you’re building a solution for users to store files. You choose AWS S3 as the location of your files because it’s easy to manage and scale. The users can name the images anything they want, but you want to shorten the names to fit with the user interface design of a new app.

Renaming files is an ideal task for a Lambda function because it’s a small isolated function, and it doesn’t have to be run immediately. Plus, it’s stateless.

The starting point for your Ruby Lambda function

The starting point for creating this function is a Lambda concept known as a handler. A handler is a method written in a Ruby file. In Ruby, file names are normally all lower case and separated by an underscore. For this example, we’ll use the default file name when creating a new Lambda, lambda_function.rb.

The lambda_function.rb file contains a method, and its default name is lambda_handler. This method contains the logic, and it will be run on an event trigger.

The first named argument for the lambda_handler method is the event. The JSON AWS event converts into a Ruby object and is assigned to this argument.

The second method argument is the context. The context is assigned to a hash, which contains methods that provide information about the function, such as the name and any limits. A full list of all the information context holds can be found in the AWS docs.

This code shows my lambda_function.rb file and the method, lambda_handler.

#lambda_function.rb
def lambda_handler(event:, context:)
end

This the base of a Lambda function and the minimum required for the Lambda to execute.

Reading information from an event

The main method that handles the processing of our event, named lambda_handler above, accepts event as an argument. This parameter is a Ruby hash converted from a JSON string containing the origin of the event and any contextual information. For our example, this will contain the name of the bucket and key of the file stored in S3.

The bucket name and key in S3 uniquely reference the image we’re storing. To retrieve these values from the event hash, update the lambda_handler method to reference the bucket name and key values from the event. See the code below for how this looks in the lambda_handler function:

def lambda_handler(event:, context:)
    first_record = event["Records"].first
    bucket_name = first_record["s3"]["bucket"]["name"]
    file_name= first_record["s3"]["object"]["key"] 
end

The above code shows retrieving the first record of the event. There will only be one record in total when adding a file to an S3 bucket. The bucket_name and file_name are then extracted from the record.

Shorten the name of the file

To shorten the name of the file, we’ll use standard Ruby libraries to extract the first 21 characters of the original file name.

One of the great aspects of using Ruby for writing Lambda functions is the simplicity of string manipulation. The below code will assign the first 21 characters of the variable file_name to the variable short_name:

short_name = file_name[0..20]

This code uses the fact that a string can be accessed the same way as arrays and selects the range from zero to 20.

Using the AWS SDK

Lambda functions are already configured to use the AWS SDK for Ruby, so no gems need to be installed before we can use the library. To reference the SDK, add a require statement to the top of your lambda_function.rb file. The below code shows the require statement at the top of the lambda_function.rb file:

require "aws-sdk-s3"

The code above loads the gem containing helper functions to communicate with the S3 service.

Moving your file from one bucket to another

To move your files from one bucket to another, reference the original image and call the move_to function on that object. The code below shows how to use the built-in SDK functions to move the file:

# Get reference to the file in S3
client = Aws::S3::Client.new(region: 'eu-west-1')
s3 = Aws::S3::Resource.new(client: client)
object = s3.bucket(bucket_name).object(file_name)

# Move the file to a new bucket
object.move_to(bucket: 'upload-image-short-name', key: short_name)

This code will create a new client in the eu-west-1 region, create a new s3 resource, and use the resource to reference a specific object: in this case, a file. The next action is to move the object to a new location. The move_to method calls the S3 service to copy the original file to the new location. Then, it deletes the original.

Putting the code together

When put together, the above code will achieve our goal of moving a file from one bucket to another, shortening the name to 21 characters.

require "aws-sdk-s3"

def lambda_handler(event:, context:)
    # Get the record
    first_record = event["Records"].first
    bucket_name = first_record["s3"]["bucket"]["name"]
    file_name = first_record["s3"]["object"]["key"]

    # shorten the name
    short_name = file_name[0..20]

    # Get reference to the file in S3
    client = Aws::S3::Client.new(region: 'eu-west-1')
    s3 = Aws::S3::Resource.new(client: client)
    object = s3.bucket(bucket_name).object(file_name)

    # Move the file to a new bucket
    object.move_to(bucket: 'upload-image-short-name', key: short_name)
end

This a working Lambda function containing the code from the previous sections of this post.

Now that we have our function, we can configure AWS to run it in a Lambda when we upload a file. To achieve this we need

  • An AWS account.
  • Two buckets—one for the initial upload and the other for storing the files once the name is changed.
  • A Lambda function triggered by upload of a file.

Setting up an AWS account

If you don’t already have an AWS account, you’ll need to set one up with Amazon. They have a generous free tier, which will cover creating this function and testing it. Amazon has a great guide on how to create and activate an AWS account, so follow this guide if you don’t already have one.

Create two S3 buckets

Create two buckets: one that will allow initial upload of the files and another to store the files once they have been renamed. Amazon has a great guide on how to create a bucket, if you wind up needing help.

Creating your Lambda function using the AWS console

You can create a function by writing the code directly into the AWS console or by writing the code on your computer and then uploading to AWS. The rest of this post covers creating your function via the AWS console.

It’s important to note that functions are located in a specific region. A region relates to a specific datacenter owned and ran by AWS. Services can’t communicate between regions easily, so make sure the Lambda is in the same region as the S3 buckets.

If you’re choosing a region for the first time, choose the region closest to you. You should also consider that some regions don’t have all the features that others do. Concurrency Labs has a great blog post called “Save yourself a lot of pain (and money) by choosing your AWS Region wisely,” and it’ll help you choose.

Create your function using the console

To create a Lambda function through the AWS console, navigate to https://console.aws.amazon.com/lambda in your browser. By default, this will open the console in your default region. My default region is eu-west-2, located in the nearest location to me, London.

Select Create function to create a new Ruby function in the eu-west-2 region.

AWS Lambda Ruby Function

The above image shows the values you should select to create a new Ruby function successfully. Once you have selected these values, click Create function. This will display the designer view shown below:

Designer View

This is a visual representation of your Lambda workflow. On the left is the trigger and on the right is the flow from the trigger to the output of the function.

Trigger your Lambda function from an event

To set up a trigger for your Lambda function, select S3 from the designer view. This will open the configuration menu for the S3 trigger, as shown below:

AWS S3 Trigger

The above trigger view shows the configuration options for S3. Select the bucket that contains the uploaded images in the Bucketdropdown and press AddYour Lambda function will now run whenever an image is uploaded to that bucket.

Configure your Lambda function

Select the Lambda function box from the designer view. This will open the Function code view, shown below the designer, already populated with an example function. Copy the code we created earlier in this blog post into the lambda_handler method in the lambda_function.rb file:

Lambda Function Ruby

Give Lambda permissions to write to S3

To allow your function to copy the file from one bucket to another the function requires some extra privileges. Select the Lambda function and scroll down to the configuration section shown below:

Lambda Execution Role

The above image shows the Lambda configuration section, focused on Execution role. Click the link named View the RenameFile-role-<unique value>. The link will redirect you to the AWS IAM service. Click Attach policy.

AWS IAM Attach Policy

The above shows the attach policy view of the IAM service.

Now, search for s3. This will show all the policies relevant to S3. Select AmazonS3FullAccess and press the Attach policy button. You should now see an extra box on the designer view, and Lambda will now have access to all buckets in S3.

AWS S3 Buckets

Test your function

Upload a file with a name longer than 21 characters to your image bucket. The file will shortly be deleted and transferred to the small names bucket and be 21 characters long. And there you go—test passed!

Writing Lambda functions in Ruby

Ruby is a great language, and I’m really happy AWS is now supporting Ruby functions in Lambda. Once you’re comfortable with the basics and want more advanced functions, Serverless Framework is a great next step. Serverless Framework allows you to package up gems to use in your function outside of those provided by Lambda. It also helps with versioning and organizing your code, along with storing the configuration for your functions.

Another tool that could speed up your development is Ruby on Jets, an easy-to-use Rails-like framework to create API endpoints and recurring jobs. These tools provide an abstraction on top of Lambda, and the generated functions can always be verified via the AWS console.

CloudWatch is the default monitoring tool created by AWS to keep track of errors in your Lambda functions. It’s a good tool, but it’s very labor intensive because looking through the CloudWatch logs is a manual process. Using a tool like Retrace could help monitor how and when each of your functions are being executed and track any errors together with context in a convenient dashboard.

Lambda is not the solution to every problem, and overuse might lead to unnecessary complexity. Take each use case one at a time and decide if Lambda is the correct solution for you.

]]>
Install Ruby on Ubuntu: Everything You Need to Get Going https://stackify.com/install-ruby-on-ubuntu-everything-you-need-to-get-going/ Sat, 08 Jun 2019 14:29:14 +0000 https://stackify.com/?p=25153 In this post, you are going to learn how to install Ruby on Ubuntu. Specifically, we’re going to install it on the current LTS (Long-Term Support) version of Ubuntu, 18.04.2.

If you’re totally new to this, don’t worry! I’ve written this guide with the assumption that you have no prior experience installing packages on Ubuntu. I will attempt to explain concepts that I believe might be confusing. However, if you’re an Ubuntu veteran or aren’t interested in a detailed explanation of what we’re doing, there’s a short and sweet TLDR section for you to install the latest Ruby package using either of the package managers we’ll look at.

Speaking of package managers, there are several ways to install Ruby. We can install and manage our installations with package managers or by using tools such as rbenv or rvm. This guide will focus on the use of package managers, specifically APT and Snap. Let’s learn a little background information and get started!

Before we start…What is Ruby?

Ruby is an open-source programming language with a strong developer focus. Created in 1996 by Yukihiro Matsumoto, Ruby became really popular in the late 2000s with the introduction of the Ruby on Rails web framework. While Ruby is used quite frequently for web development, it’s also popular as a scripting language.

Ruby is known for being easy to learn and fun to use. So let’s find out how easy it is to get up and running!

What we’re going to do

  1. Understand the difference between Snap and APT
  2. Install Ruby on Ubuntu with APT
  3. Install Ruby on Ubuntu with Snap

What you’ll need

  • An internet connection
  • Administrator privileges
  • A few minutes

TLDR—Run these commands from the Terminal application

Here are the commands to install with APT:

sudo apt update
sudo apt install ruby

Here is the command to install with Snap:

sudo snap install ruby –classic

Package managers: The difference between APT and Snap

Hold on! What’s a package manager?  A package manager is an application whose job is to manage software on your computer. In this case, managing means installing, updating, and removing software as needed. Package managers will install software in a consistent manner and keep your computer tidy. They save you the trouble of needing to maintain and update each piece of software on your machine individually.

APT and Snap are package managers.  APT refers to a suite of tools is a suite of tools for managing packages. When I mention APT in this guide, I’m referring specifically to the apt command line tool. Similarly, Snap is also a command line tool within the Snapcraft toolset. Snapcraft as a whole can be thought of as an ecosystem for package development and distribution. The Snapcraft ecosystem integrates with the Ubuntu Software Store, but if you’re installing a tool like Ruby, you should familiarize yourself with running commands in a shell.

APT is the built-in package manager for Ubuntu. If you’ve used Ubuntu for a while, you might be asking, “Why not apt-get?” The apt-get tool still exists. However, since Ubuntu 16.04, a more user-friendly command, apt, has been included with the base installation. The apt command wraps some of the most commonly used functionality from the apt-get and apt-cache commands into a single command. The apt command makes the process of searching and installing packages easier for users who don’t need all the advanced functionality or fine-grain control that apt-getand apt-cache provide.

Snap is a relatively new package manager developed by Canonical, the company behind Ubuntu. Snap uses its own package format and provides a more universal way to develop and distribute packages for Linux systems.

Why discuss both?

We won’t go too in depth here, but the basic premise is that package management has been a sticky problem for Linux systems. There are many different Linux distros, which use different types of packages. Also, packages can be tied to specific releases. This means that for a developer to release one package, that developer will have to make several versions of that package to ensure that it works as expected across all the different distros and versions. For users of these systems, this means that updates to the software we use can be slow.

The Snapcraft ecosystem is attempting to alleviate this package versioning and distribution problem. By providing distro and version agnostic packages, called snaps, it’s attempting to increase the speed at which developers can release changes and features to users!

What does that mean for me?

APT is traditionally the means to install software on your Ubuntu installation. It will work perfectly fine in this case. However, you’ll notice later in this guide that when we install Ruby from APT, the version is going to be a bit older (2.5.1p57). At the time of this writing, the current stable releases of Ruby are 2.6.3 and 2.5.5. However, if we install with Snap, we’ll get the latest stable release, 2.6.3. The Snap CLI came installed on Ubuntu 18.04.2, so you should have no problem if you’re using that or even a version as old as 16.04.

If you want the latest version of a package, and you are on Ubuntu 16.04 or later, use Snap. If you’re working on an older version of Ubuntu, or aren’t concerned with having the latest version of Ruby, you can use APT.

Install Ruby on Ubuntu with APT

Installation with APT is very straightforward. We’re going to execute a couple of commands, and we’ll be ready to go. This process should be the same regardless of whether you’re working on a fresh install or an existing system. We’re going to use the Terminal application to update the repositories APT knows about in order to make sure it has the latest packages available. After that, we’re going to install Ruby.

Step 1: Open the Terminal application

First, we need to open up Terminal. To do that, click on the “Show Applications” button on your desktop. If you don’t know what that is, it’s a button that looks like a nine-dot grid.

Type in “terminal” and select the application. The application icon should look something like this:

Terminal is a program that gives us access to the shell. The shell is a CLI that gives us a way to interact with the operating system via commands. When the shell opens, you will be presented with a prompt. My prompt looks like this:

chris@chris-VirtualBox:~$

The first section, chris@chris-VirtualBox, refers to the logged in user. The tilde character following the colon indicates what directory we’re in. By default, the shell will open in your home directory, and the tilde is an alias for that directory. The home directory is a special directory on Unix-like systems that belongs to you, the logged-in user. The dollar sign indicates where the prompt ends and your input begins.

Before we move to the next step, let’s make sure that Ruby isn’t already installed. We can run this command:

which ruby

If Ruby is installed, you will receive some output after the prompt that tells you where Ruby is installed on your machine. If it’s not installed, you’ll be presented with another prompt. Ruby doesn’t come installed on Ubuntu, so unless you or someone else has installed it, you should receive an empty prompt like this:

which ruby
chris@chris-VirtualBox:~$

Now that we’ve verified that Ruby is not installed, let’s do our APT update.

Step 2: Update APT

Before we install Ruby, we want to make sure that APT has the latest package lists. APT will come installed with a list of packages to download when installing various pieces of software. When we update it, it checks for the latest lists that determine if newer versions are available, or if existing packages have additional dependent software that we need to install.

The command is pretty straightforward.

sudo apt update

This command will prompt you for your password if you have administrative access, which you should if you’re working on a system of your own. Otherwise you’ll need to contact whoever administers the system you’re working on.

The actual command we’re running is apt update, but we’re prefixing it with a special command called sudo. A simple explanation for our purposes is that the sudo command takes another command and executes it with elevated permissions. If you try to run apt update on its own without the sudo command, you’ll get a permission denied error.

Now that we’ve updated APT, let’s go ahead and install Ruby!

Step 3: Install Ruby

We can find the source of the package for Ruby with the apt list command. Here’s the command and the output for me:

apt list ruby
Listing... Done
ruby/bionic 1:2.5.1 amd64

We’ll see that there’s a Ruby package available for bionic. Bionic refers to “Bionic Beaver,” which is the codename for the Ubuntu 18.04.2 release. Let’s install this package. It’s as easy as:

sudo apt install ruby

You’ll receive some output that looks like this:

Reading package lists... Done
Building dependency tree 
Reading state information... Done
The following additional packages will be installed:
fonts-lato javascript-common libjs-jquery libruby2.5 rake ruby-did-you-mean
ruby-minitest ruby-net-telnet ruby-power-assert ruby-test-unit ruby2.5
rubygems-integration
Suggested packages:
apache2 | lighttpd | httpd ri ruby-dev bundler
The following NEW packages will be installed:
fonts-lato javascript-common libjs-jquery libruby2.5 rake ruby
ruby-did-you-mean ruby-minitest ruby-net-telnet ruby-power-assert
ruby-test-unit ruby2.5 rubygems-integration
0 upgraded, 13 newly installed, 0 to remove and 312 not upgraded.
Need to get 6,156 kB of archives.
After this operation, 27.8 MB of additional disk space will be used.
Do you want to continue? [Y/n]

There are a few things happening here. APT is telling us that additional packages will be installed. These are the tools that the maintainers of the Ruby package think we should have with the regular Ruby installation. It will install packages like the build tool, Rake, the Ruby package manager, Gem, and some testing tools.

After sections detailing what will be installed and other suggested packages, we can see a summary telling us that we’ll be installing 13 new packages and that 27.8 MB of disk space will be used.

Now that APT has listed the effects of the installation, we’re given a yes or no option to proceed. When receiving a prompt in the shell, the convention is that the uppercase letter is the default. So with [Y/n], we can either type Y or just hit the Enter key to finish the installation.

Step 4: Verify the installation

This step is mostly for our own edification. We can verify the installation a couple of ways. We can run the whichcommand again, and also use the ruby -v command to check the installed Ruby version. Here’s what it looks like on my machine:

which ruby
/usr/bin/ruby

ruby -v
ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux-gnu]

We can see that our Ruby installation lives in the /usr/bin directory and that the version is 2.5.1. Very cool! We have successfully installed Ruby with APT.

If you’d rather use Snap but have been following to this point, you can remove your Ruby installation just as easily by doing this:

sudo apt remove ruby

Remember those extra packages that were installed along with Ruby? When we remove Ruby this way, we actually haven’t removed those packages. Dependencies such as this are not marked as auto-removable when their parent dependency is removed. We can remove them by running this command:

sudo apt autoremove

Our machine is now back to where it was when we started. Let’s go ahead and install with Snap.

Install Ruby on Ubuntu with Snap

Installing with Snap is pretty easy! We’re going to open the terminal and verify that the Snap CLI tool is installed. Once we verify that, we’re going to simply install Ruby with Snap.

Step 1: Open the Terminal application

This is actually exactly the same as the first step for the APT installation. If you don’t know how to open the Terminal app, please go to step 1 in the APT section above. That step will also show you how to determine if you already have Ruby installed.

Step 2: Verify that Snap is installed

In order to verify that Snap is installed, we can use the which command to see where it lives and the snap –versioncommand to see what version we are running. The which command is sufficient on its own, but I have a habit of checking the version on command line tools. It’s a quick way to verify the tool is there and doesn’t take too long.

which snap
/usr/bin/snap

snap --version
snap 2.39
snapd 2.39
series 16
ubuntu 18.04
kernel 4.18.0-15-generic

If this didn’t work and Snap is not installed, you can follow the thorough installation instructions that Canonical provides.

Step 3: Install Ruby

If you followed the APT installation instructions, you might be wondering why we don’t need to update the package list for Snap. The docs for Snap let you know that packages are refreshed by the background Snap daemon process four times a day. However, it’s possible to retrieve the latest packages on demand if you so choose by running sudo snap refresh.

It’s pretty easy to install Ruby with Snap. Here’s the command:

sudo snap install ruby --classic

There are two things to note about this command. This command, like the apt install or apt update commands, requires elevated privileges. As such, we’ll have to use sudo and give our credentials.

The second interesting thing about this install command is the –classic argument. This is a special flag passed to snaps that require access to system resources. Classic is a type of confinementSnaps are installed in an area separate from the normal executables on the system, and they have their permissions and access confined by Snap. The team behind Snap audits any program that requires traditional access to the operating system, like our Ruby installation. So, we need to provide the –classic argument.

We have installed Ruby with Snap. Let’s go ahead and verify the installation.

Step 4: Verify the installation

This is very similar to verifying the installation we did with APT. The differences we’ll note are that Ruby is installed in a different directory and the version is different (at least at the time of this writing).

If you ran this installation process immediately after removing the Ruby we installed with APT, you will need to close and reopen Terminal to run this step!

Again, we’re going to use which to see the install location and check the version with ruby -v. Here’s the output on my machine:

which ruby
/snap/bin/ruby

ruby -v
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-linux]

We can see that our Ruby installation lives in the /snap/usr/bin directory and that the version is 2.6.3. Installing with Snap was pretty snappy!

What’s next?

We’ve gone over how to install Ruby on Ubuntu with both the APT and Snap package managers. We’ve also discussed some of the basics around package management and the difference between APT and Snap.

If you’re just starting out, it might be a good idea to look at some learning resources for Ruby that I linked in the introduction.

If you’re planning on using Ruby to write a cool business app, take a look at Retrace. Retrace can do all sorts of things for you, including helping you understand your application’s performance.

Start Free Trial
]]>
Install Ruby on Windows: Everything You Need to Get Going https://stackify.com/install-ruby-on-windows-everything-you-need-to-get-going/ Fri, 07 Jun 2019 16:23:19 +0000 https://stackify.com/?p=25159 Ruby is a well-established and well-regarded programming language. Once upon a time, installing Ruby on Windows came with problems, but things have come a long way. Today, there’s no reason someone couldn’t write Ruby code on any platform.

First released in the mid-1990s, Ruby’s popularity soared with the release of Ruby on Rails in 2005. Ruby is primarily an object-oriented programming language (OOP), but it offers powerful aspects of the functional programming paradigm as well. It’s less verbose than many other languages, offering a concise and straightforward syntax. This simplicity makes it a good language to start with. The popular Ruby on Rails web framework also powers many large websites, meaning Ruby is here to stay.

Let’s take a look at how to set up a functioning Ruby environment on your Windows computer.

Getting some respect

Ruby’s difficulties on Windows stem from the fact that it’s very different, under the covers, from both Linux and macOS. Those two operating systems have similar “toolchains” because both are based on Unix. This means that they can use the same compiler, shared library system, and other tools to build the Ruby interpreter and Ruby libraries, which are called “RubyGems.”

Ruby is an open-source language written by volunteers. It was developed on Unix-based computers, so making the language work there came first. There’s always been an effort to make it work on Windows as well, but the Unix-like environments got priority.

For many years, trying to develop Ruby code on a Windows computer meant dealing with issues that someone using a Mac or Linux computer wouldn’t face. To a certain extent, that’s still true. When seeking help for a problem you run into, you’ll likely find fewer search results for Windows. Plus, you may find that less common libraries don’t even offer a Windows version.

And if you’re planning on deploying your code, you should think about what that platform will be. For example, if you want to write a Ruby on Rails web application, you’ll likely be deploying it onto a Linux web server. It’s always best to keep the development environment as close as possible to the production environment so that you don’t get any surprises when your code goes live.

Two ways to get there

One of the most surprising and pleasant developments in the software world in recent years has been Microsoft warming up to open source. The tech giant now has over 2,400 repositories on GitHub, and the description on their GitHub profile says “open-source, from Microsoft with love.” Their open-source projects include the popular Visual Studio Code programming text editor. They’ve also embraced open source by bringing Linux to Windows!

That’s right, Windows 10 allows you to install a Linux “subsystem” on the same computer. This means you can install and run Linux applications. This also means that you can use Linux package managers to install the traditional Ruby environment. It’s called the Windows Subsystem for Linux, and we’ll cover how to get a working Ruby installation with the approach below.

However, if you have a computer running an older version of Windows, that option isn’t available to you. But fear not. There’s still active development on Ruby for Windows, including right up to the most recent version of Ruby. This project is called RubyInstaller, and it works its magic by using the MSYS2 system for providing Unix-like libraries on Windows as well as MinGW (Minimal Gnu for Windows), which is a large library of Unix-like packages that work on Windows.

But you don’t need to worry about those details. RubyInstaller provides you with a straightforward, mostly GUI-based experience to get Ruby up and running on your older Windows machine. Let’s look at this option first.

Using RubyInstaller

To use RubyInstaller, you need to first download it from their downloads page. Notice that the list of options has “with Devkit” and “without Devkit” sections. The Devkit versions install the MSYS2 system, which will be required if you need to install RubyGems that require compilation. If you’re just going to play around with plain old Ruby, you might be able to get away with the non-Devkit version. But why limit yourself? If you want to work on a Ruby on Rails app, you’ll definitely need to compile gems, so you need the Devkit.

Ruby Installer for Windows

Also note that there are various Ruby versions available, and there are both x86 and x64 packages. Currently, there’s an arrow pointing at the 2.5.5-1 (x64) package. That’s because it’s still the preferred Ruby version for most people. Ruby 2.6.3 is still fairly new, so it won’t have as many gems available. Also, as it says on the page, “the 32 bit (x86) version is recommended only if custom 32-bit native DLLs or COM objects have to be used.” You should stick with x64.

Download that and run it to get started. You’ll first need to accept the license agreement.

Ruby Install Windows License Agreement

On the next screen, be sure to check the MSYS2 development toolchain option:

Ruby Installer Select Components

Then click “Next” and grab a cold one. It takes a few minutes to install everything.

Tooling up with the MSYS2 toolchain

Once you’ve done that, another important checkbox appears on the final screen of the installer: “Run ‘ridk install’ to set up MSYS2.” The GUI installer won’t do that part for you, so use this checkbox to kick that off next:

Install Ruby on Windows setup

Installing the development toolchain is a command-line process, so a terminal window will open to complete this part:

Ruby Installer for Windows

This “ridk install” command asks which components you want to install. It’s fine to just hit “Enter” to accept the default. This will install the base MSYS2 system, check for updates to it, and then install the development toolchain.

Once that’s rolling, you’ll see a lot of output streaming by. It takes at least as long as installing Ruby did. When you’ve done that, you should see the message “install MSYS2 and MinGW development toolchain succeeded.” Oddly enough, that leaves you at the same install prompt. Just hit “Enter” again to get out of that. The terminal window will close.

Ready to rock Ruby on Windows!

In order to check out your fresh Ruby install, you need to open a terminal window again. You can do so by opening the Windows menu and typing “cmd” in the search box. At the command prompt, type “ruby -v” and hit “Enter.” You should see something like this:

Ruby Installer Windows Command Prompt

And running the command “gem list” will show you what RubyGems came with your fresh install:

Ruby Gem List Windows

You can also run “irb,” the interactive Ruby shell:

Ruby Shell Windows

Try out some Ruby!

Ready for Rails?

You can then go on to install Ruby on Rails, which is a RubyGem. However, note that Rails is generally used to develop database-backed web applications. That means that it needs a database server to talk to. So when you try to generate a new Rails application without any options specified, you’ll get an error because, by default, Rails tries to use the SQLite database engine. The Rails team chose SQLite as the default because it’s often already installed on Mac or Linux and because it doesn’t need a database server process. It stores its data in a file on disk. 

Most serious applications use a more robust database server, like MySQL or PostgreSQL. So you may want to install one of those on your Windows machine and then generate your Rails app with the option to specify that database driver.

Try Stackify’s free code profiler, Prefix, to write better code on your workstation. Prefix works with .NET, Java, PHP, Node.js, Ruby, and Python.

Using the Windows Subsystem for Linux

As mentioned previously, with Windows 10, Microsoft started offering a standard way to run a Linux command line on Windows computers. This is called the Windows Subsystem for Linux (WSL), and it’s fairly easy to get started with. It is also a good way to get working with Ruby on Windows. You even get your choice of Linux distro. If you’re not too familiar with Linux, a “distro” is the distribution of Linux. Common distros include Red Hat, CentOS, Debian, Ubuntu, etc. For this tutorial, we’re going to use Ubuntu.

To use the WSL, you first need to enable it. There are tutorials online that tell you how to do this by running a command in an admin console (e.g., “Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux”) but you don’t have to bother with that. It’s a standard Windows feature now, so you can turn it on in the Windows control panel. 

Once you have the control panel open, choose “Programs” and then “Turn Windows features on or off.” Scroll down to the bottom of the list and check the checkbox next to “Windows Subsystem for Linux,” then click “OK.” Then reboot the computer.

Hello Linux!

After your computer has rebooted, you can install the Linux distro of your choice from the Microsoft Store. We’re going to use Ubuntu 18.04 LTS (which stands for “long-term support”):

Once that’s finished installing, you can quit the store application. Your spiffy new Ubuntu command line will be available as an app from the Windows menu:

Running that opens a terminal window and kicks off the setup steps for this mini Linux install. There are only two steps: enter a username and a password. They can be the same as your Windows username and password or different. After setting that up, you should have a working Bash prompt!

If you’re not familiar with Bash, it’s the Bourne Again SHell, the most common terminal shell program in Unix/Linux. There are lots of tutorials online about how to use the Linux command line. A few commands are “ls” to list files/directories in the current directory, “cd <path>” to change to a given directory, and “pwd” to print your current directory path.

From here on, you could probably follow any tutorial on installing Ruby on Ubuntu. But I won’t leave you hanging. Read on for specific steps to Ruby joy.

Installing Ruby on the WSL

The easiest way to install Ruby on Ubuntu is with a package manager. And for Ubuntu, that means “apt.” You need to be an administrator—or as it’s called in the Unix world, a “superuser”— to install packages. The way to run a command as the superuser is by putting the command “sudo” (“SUperuser DO”) before it.

Before we tackle installing Ruby though, let’s make sure our new Ubuntu install is up to date. Run the following in your Bash terminal:

sudo apt update && sudo apt dist-upgrade && sudo apt autoremove && sudo apt clean

This will fetch a bunch of packages and then ask you to make sure you want to install them. You can just hit enter to say yes. Then comes more waiting! It’s likely that you will have dozens of updates to install.

Once that’s done, you may get another question asking you if you want to remove some packages. Go ahead and hit “Enter” to say yes.

Once you have your prompt back, you’re ready to install Ruby! Do that with this simple command:

sudo apt install ruby-full

This does some dependency-checking and shows you what you need to install to get Ruby working:

As always, hit “Enter” to accept, and away we go. There sure is a lot of waiting involved in installing software, isn’t there? But once apt has done its magic, we’ll have a working Ruby 2.5.1 install in our Linux Subsystem. As with RubyInstaller, you can verify the Ruby install by running “ruby -v”:

And you can check the RubyGems installed with “gem list”:

This is almost the same list as we got with RubyInstaller. And again, you can run “irb” to play around with Ruby.

Bonus points!

Let’s go a bit further with our WSL Ruby install and see what it takes to get Ruby on Rails set up. This Ubuntu install doesn’t yet have the ability to compile gems, and Rails will need that. In particular, Rails wants to use the Nokogiri gem for parsing HTML, and that requires compiling its native extensions. The Nokogiri installation page gives us a list of apt packages to install to prepare for Nokogiri: “build-essential, patch, ruby-dev, zlib1g-dev, and liblzma-dev.”

However, we’re also going to have the same problem with needing SQLite to use the default Rails app generator. Luckily, apt has an SQLite library that fits the bill: libsqlite3-dev. Finally, Rails uses Node.js to do its JavaScript and asset packaging, so we want apt to install that as well.

Let’s add all that to the apt command Nokogiri gave us and run it:

sudo apt install build-essential patch ruby-dev zlib1g-dev liblzma-dev libsqlite3-dev nodejs

After that long list of packages is installed, you can run “gem install rails.” Windows Defender will probably make sure you’re okay with Ruby making network calls:

Go ahead and allow it and watch the gems fly by. Compiling Nokogiri will take a bit of time as well.

WSL file system oddities

With Rails installed, you are ready to generate your first Rails app. But before we do that, you should know something about working with files in the Linux Subsystem.

Running the WSL terminal puts you in your WSL home directory. If you open an Ubuntu terminal and run “pwd,” you will see “/home/<your username>.” This is basically a make-believe directory living within the WSL application. You can create a file there and then search for it in Windows Explorer. It won’t find it.

To be able to work on your Ruby code with a Windows GUI text editor (like VSCode), you should put your code someplace Windows Explorer can find it.

Your computer’s C drive is visible in the WSL at the path “/mnt/c.” (“mnt” is a Linux convention for the location where drives are mounted and “c” refers to your C drive). So if you run “cd /mnt/c,” you’ll be at the root of the C drive. You can create a directory for your work here, either through Windows Explorer or by running “mkdir ruby_work” in the Bash terminal.

Rolling on Rails!

You can then generate a new Rails app with “rails new <app name>.” Rails will create a directory named with your app name and an initial project structure inside. It will also install gems just for your app.

In the early years of Rails, developers found that it was problematic working on several Ruby or Rails apps on the same machine and needing different versions of the same gems per app. Bundler came along to solve this problem. You list your app’s gems in a Gemfile and then run the command “bundle install” to install those gems just for that app.

Start the development server by running “rails s” in the app directory. Then you can open a browser and go to http://localhost:3000 and see the default Rails start page!

Rocking the Ruby

Whichever approach you took, you should now have a functioning Ruby install on your Windows machine. Note that these aren’t the only two ways to get Ruby working on your machine. You can also use a virtual machine application like VirtualBox or VMWare to create a Linux virtual machine. This would be similar to the WSL approach, but you could install a desktop Linux distro so that you can interact with the UI. Vagrant uses VM software, but it allows you to choose from ready-to-go machine images and has a way to make the code on your Windows machine visible to the VM.

Another thing to consider as you sail away on your Ruby journey: what should you do when you wind up working on multiple Ruby projects that require different versions of Ruby? To do this, you can use a Ruby version manager like RVM or RBenv.

Finally, once you’ve built something with Ruby, you’re going to want to keep an eye on its performance, watch for errors, and debug production issues. For this, you should take a look at Retrace. It can help you keep an eye on your code from top to bottom!

Start Free Trial
]]>