Ruby: Sanitizing User Input & Control Structures

Free Ruby on Rails Tutorial

This exercise is excerpted from Noble Desktop’s past web development training materials. Noble Desktop now teaches JavaScript and the MERN Stack in our Full Stack Development Certificate. To learn current skills in web development, check out our coding bootcamps in NYC and live online.

Note: These materials are provided to give prospective students a sense of how we structure our class exercises and supplementary materials. During the course, you will get access to the accompanying class files, live instructor demonstrations, and hands-on instruction.

Topics covered in this Ruby on Rails tutorial:

Sanitizing user input, Integers & decimals, If/else, unless, & case statements, Constants, Symbols

Exercise Overview

We often need to clean up the text (input) that users give us, for example when they fill out an online form. In this exercise you will learn how to sanitize strings, work with integers and decimals, and use if/else, unless, and case statements. You’ll also learn about more important Ruby concepts like constants and symbols.

Sanitizing User Input

  1. If you closed Terminal, closed the window, or exited IRB, open a Terminal window and type the irb command.

  2. One common and important use of string methods is sanitizing user input. Imagine you are a sloppy user and you are careless about filling out HTML forms. Type the following, including the extra spaces and the close quote on a separate line exactly as shown below:

    signup = "   fluffy@gmail.com
    "
    

    Terminal should return: " fluffy@gmail.com\n", representing that extra line break as \n and including the extra spaces at the beginning of the string.

  3. If we tried to email that address, it wouldn’t work correctly, or the extra \n might create strange formatting. Clean it up by typing:

    signup.strip
    

    Terminal should return: "fluffy@gmail.com" and we can see that the powerful .strip method has quickly and easily purged the sloppy user entry of all the white space and line breaks.

  4. Type the following:

    signup
    

    Oh no! IRB returns the sloppily formatted email again. Let’s use the exclamation point to make this method permanent.

  5. Make the method permanent by typing:

    signup.strip!
    signup
    

    Success! Terminal should return the (permanently) sanitized string.

Integers & Decimals

Any good language has support for numbers and arithmetic functions, and Ruby is no exception. Numbers in Ruby work much like you’d expect: there are integers and decimals (aka float values) and they’re pretty easy to understand.

  1. Type the following:

    1
    

    Terminal will return 1

  2. Type:

    1 + 1
    

    Terminal will return 2

  3. Type the following:

    1.5 + 1.45
    

    Decimals behave similarly to integers, so Terminal will return 2.95

  4. Try mixing integers and decimals by typing:

    1 + 1 + 1.5
    

    It is valid to mix integers and decimals, and Terminal will return 3.5

  5. Let’s see what happens when we divide two integers. Type the division function shown below:

    1/2
    

    Terminal will return 0. Were you expecting 0.5? Because we divided two integers, Terminal returned an integer (it left off the decimal value of .5).

  6. In order to get a decimal value from the same division function, try typing this:

    1.0/2.0
    

    Terminal will return 0.5

  7. You can see that numbers are fairly straightforward in Ruby, but one problem you’ll likely encounter is dealing with numbers that are actually strings, which often turn up as the result of user input. Let’s try to add a number that is actually a string (the one enclosed in quotes) to a number by typing:

    "1" + 1
    

    Terminal should return an error message which means that Ruby doesn’t know whether we want to add these values or concatenate them. (Remember, we were using the plus sign to concatenate two strings earlier.)

  8. The solution, whenever you’re dealing with a number that is a string, is to append the function to_i (where i stands for integer) by typing:

    "1".to_i + 1
    

    Success! We have treated a number that is actually a string as a numeric value by appending the to_i function, and Terminal should return 2.

  9. If you have a number that is a string that’s a floating value (decimal), you can treat it as a numeric value by appending the to_f function. Try typing:

    "1.5".to_f + 2.0
    

    Terminal should return 3.5

  10. Suppose you did really want to concatenate the values. In that case, you would append the to_s function (where s stands for string) to a numeric value. Type:

    "1" + 1.to_s
    

    Terminal should return "11". It hasn’t done any math, because we told it to treat both elements as strings. Terminal simply took the two strings (each consisting of the single character 1) and crammed them together.

  11. You should be getting the hang of how the powerful functions to_s, to_i, and to_f can make Ruby treat strings as numeric values and vice versa. Try combining a text and numeric string by typing:

    "easy as " + 123.to_s
    

    Terminal should return a string that reads "easy as 123". Success!

If/Else, Unless, & Case Statements

A control structure is a block of programming that analyzes variables and chooses a direction in which to go. Think of them as tests to see if something will happen.

One of the fundamental control structures of any programming language is the if/else statement, which works in a fairly straightforward way in Ruby. Let’s see it in action.

  1. Type the following simple if statement:

    if 2 > 1
       "All is right with the universe today"
       end
    

    Terminal should return "All is right with the universe today"

  2. Type the following simple if/else statement:

    if 1 > 2 and 3 <= 2
       "Something is very wrong!"
       else
          "Phew! Basic principles of math are still in effect"
       end
    

    Terminal should return the else statement: "Phew! Basic principles of math are still in effect"

    NOTE: The <= above stands for less than or equal to (≤) but is easier to type.

  3. Ruby has a version of the “else if” statement found in several other programming languages, except in Ruby it’s spelled elsif. Pay close attention to that spelling. It’s not just missing a space, there is no e at the end of else! It’s elsif, not elseif! We get burned all the time by accidentally adding an e to the end of else. Be careful of that. Let’s try it out. Type the following:

    animal = "cat"
    if animal == "dog"
       "Arf!"
       elsif animal == "cat"
       "Meow!"
       end
    

    The == operator checks if the value of two things are equal or not. If they are, then the condition becomes true, and if not it becomes false. Because we set animal equal to cat, in response to this simple else/if (elsif) statement, Terminal should return "Meow!" If you got a response of nil, you most likely added an extra e in the middle of elsif. Pay close attention to the missing e in the middle!

  4. Ruby has another, even more unique way of writing if. In the case that your if statement is only a single line, you won’t need the end keyword. This is used very frequently by Ruby developers. Instead of that statement we just wrote, you could write just one line of code that looks like this. Type:

    "Meow!" if animal == "cat"
    

    Terminal should return "Meow!" as expected. This was so much simpler than the previous method!

  5. Ruby also has a keyword unless, which is the opposite of if. Try typing:

    "Arf" unless animal == "cat"
    

    Terminal should return nil, because animal is indeed equal to cat.

  6. In Ruby, we use an exclamation point followed by an equal sign != to mean ≠. Used together with unless and other methods, you can create some pretty mind-bending double-negatives, triple-negatives… Try typing this:

    "Meow" unless animal != "cat"
    

    Terminal returns "Meow" because we have not succeeded in confusing Ruby, or ourselves: animal is indeed equal to cat.

  7. Ruby also uses case statements, which are similar to switch statements in some other programming languages. Let’s create a method in order to invoke this case statement a few times. Type the following:

    def birdsong(bird)
       case bird
          when "owl"
          "Hoot"
          when "crow"
          "Caw Caw"
          else
             "tweet"
          end
       end
    
  8. We have just created a simple case statement. Test how it works by typing:

    birdsong("owl")
    

    Terminal should return "Hoot!"

  9. Type:

    birdsong("robin")
    

    Terminal should return the default "tweet"

  10. Type the following:

    birdsong("crow")
    

    Terminal should return "Caw Caw". So we have created a simple function using a case statement that supplies a default return "tweet" for any species of bird, and, in the case of owls and crows, returns a specialized call.

Constants

In Ruby, constants are written in UPPERCASE, and once defined, they are not intended to be changed. Let’s start with another universal constant: pi.

  1. Type the following, making sure PI is uppercase, defining it as a constant:

    PI = 3.14159
    
  2. Type the following, in uppercase:

    PI
    

    Terminal should return the value we just assigned the constant PI, and now we can use this unchanging constant in functions.

  3. Type the following:

    diameter = 2
    circumference = PI * diameter
    

    Terminal should return 6.28318 (the circumference of that particular circle).

  4. Once you define constants, you really ought not to change them. Ruby will let you, though, so let’s pretend there was a catastrophic shift in the laws of the universe and change the value of PI by typing:

    PI = 12061
    

    Ruby let us re-define PI, but not without a warning that reads warning: already initialized constant PI. Re-defining constants can be a real source of bugs, so it’s a good thing to know to watch out for this warning.

  5. One good way to make sure that constants don’t get re-defined is to break them off into modules; in fact, constants are most frequently encountered as parts of modules. For example, PI comes as part of the Math module that is included with Ruby. A constant within a module is called by invoking the module’s name, followed by two colons, and then the name of the constant. Do that by typing the following:

    Math::PI
    
  6. Terminal should return a version of pi that is way more precise than the one we typed a moment ago. Let’s try calling our own re-defined PI again by typing:

    PI
    

    Terminal should return 12061, and we can see that our newly-defined PI remains intact because it exists separately from the PI in Ruby’s Math module.

Symbols

Symbols are a very unique Ruby feature. A symbol is basically a text value that starts with a colon, such as :meow or :arf. They are most commonly used to communicate values and settings internal to the application (e.g., not displayed to the end user directly).

  1. Let’s create a function that takes advantage of the power of symbols. Type the following:

    def speak(animal)
       case animal
          when :dog
          "arf"
          when :cat
          "meow"
          when :mouse
          "squeak"
          end
       end
    
  2. Let’s try it out. Type the following:

    speak :cat
    

    Terminal should return "meow".

  3. Why use symbols rather than strings? For one, they’re more memory-efficient than strings. To see just how simple they are, try typing the following, which will return an error message:

    :mouse.upcase!
    

    You’ll get an undefined method error because a symbol cannot change case, or be reversed, or perform any number of string-related functions. Because symbols can’t do all the things that strings can do, they are simpler, cleaner, and make your program run faster.

    Symbols also provide a convenient way to distinguish between values which are internal to the application, and those that will be visible to an end user. Once you get used to symbols, the use of strings to do similar things in other programming languages will seem a little clunky!

  4. You might also have been wondering why we haven’t been using parentheses. Well, Ruby lets you omit parentheses for uncomplicated function calls. Try typing this:

    speak :mouse
    speak(:mouse)
    

    The second option works as well as the first, but it’s common practice to omit the parentheses.

    NOTE: We have been using IRB in Terminal. IRB is not Rails. Rails has its own console, which we’ll be looking at later. There are a lot of functions that you’ll become familiar with later on, in Rails, that won’t work in the environment that we’ve been using in this exercise, IRB. (Because IRB is a pure Ruby console, it does not load all of the code and additional libraries that Rails does.)

How to Learn Coding

Master coding with hands-on training. Learning how to code in JavaScript, Python, and other popular languages can pave the way to a job in tech, such as web development, data science & analytics, or software engineering.

Yelp Facebook LinkedIn YouTube Twitter Instagram