Home > Articles > Programming > Ruby

Rails-Flavored Ruby

This chapter is from the book

4.2 Strings and Methods

Our principal tool for learning Ruby will be the Rails console, which is a command-line tool for interacting with Rails applications. The console itself is built on top of interactive Ruby (irb), and thus has access to the full power of Ruby. (As we'll see in Section 4.4.4, the console also has access to the Rails environment.) Start the console at the command line as follows:

$ script/console
Loading development environment (Rails 2.3.8)
>>

By default, the console starts in a development environment, which is one of three separate environments defined by Rails (the others are test and production). This distinction won't be important in this chapter; we'll learn more about environments in Section 6.3.1.

The console is a great learning tool, and you should feel free to explore—don't worry, you (probably) won't break anything. When using the console, type Ctrl-C if you get stuck, or Ctrl-D to exit the console altogether.

Throughout the rest of this chapter, you might find it helpful to consult the Ruby API.4 It's packed (perhaps even too packed) with information; for example, to learn more about Ruby strings you can look at the Ruby API entry for the String class.

4.2.1 Comments

Ruby comments start with the pound sign # and extend to the end of the line. Ruby (and hence Rails) ignores comments, but they are useful for human readers (including, often, the original author!). In the code

# Return a title on a per-page basis.
def title
.
.
.

the first line is a comment indicating the purpose of the subsequent function definition.

You don't ordinarily include comments in console sessions, but for instructional purposes I'll include some comments in what follows, like this:

>> 17+42 # Integer addition
=> 59

If you follow along in this section typing or copying-and-pasting commands into your own console, you can of course omit the comments if you like; the console will ignore them in any case.

4.2.2 Strings

Strings are probably the most important data structure for web applications, since web pages ultimately consist of strings of characters sent from the server to the browser. Let's get started exploring strings with the console.

>> ""           # An empty string
=> ""
>> "foo"        # Anonempty string
=> "foo"

These are string literals (also, amusingly, called literal strings), created using the double quote character " . The console prints the result of evaluating each line, which in the case of a string literal is just the string itself.

We can also concatenate strings with the + operator:

>>  "foo" + "bar"    # String concatenation
=> "foobar"

Here is the result of evaluating "foo" plus "bar" in the string "foobar" .5

Another way to build up strings is via interpolation using the special syntax #{}:6

>>  first_name = "Michael"    # Variable assignment
=> "Michael"
>>  "#{first_name} Hartl"     # Variable interpolation
=> "Michael Hartl"

Here we've assigned the value "Michael" to the variable first_name and then interpolated it into the string "#{first_name} Hartl". We could also assign both strings a variable name:

>>  first_name = "Michael"
=> "Michael"
>>  last_name = "Hartl"
=> "Hartl"
>>  first_name+""+ last_name        # Concatenation, with a space in between
=> "Michael Hartl"
>>  "#{first_name} #{last_name}"    # The equivalent interpolation
=> "Michael Hartl"

Note that the final two expressions are equivalent, but I prefer the interpolated version; having to add the single space "" seems a bit awkward.

Printing

To print a string, the most commonly used Ruby function is puts (pronounced "put ess", for "put string"):

>> puts "foo"    # put string
foo
=> nil

The puts method operates as a side-effect: the expression puts "foo" prints the string to the screen and then returns literally nothing: nil is a special Ruby value for "nothing at all". (In what follows, I'll sometimes suppress the => nil part for simplicity.)

Using puts automatically appends a newline character \n to the output; the related print method does not:

>> print "foo"    # print string (same as puts, but without the newline)
foo=> nil
>> print "foo\n"  # Same as puts "foo"
foo
=> nil

Single-Quoted Strings

All the examples so far have used double-quoted strings, but Ruby also supports single-quoted strings. For many uses, the two types of strings are effectively identical:

>>  'foo'         #A single-quoted string
=> "foo"
>>  'foo' + 'bar'
=> "foobar"

There's an important difference, though; Ruby won't interpolate into single-quoted strings

>>  '#{foo} bar'    # Single-quoted strings don't allow interpolation
=> "\#{foo} bar"

Note how the console returns values using double-quoted strings, which requires a backslash to escape characters like #.

If double-quoted strings can do everything that single-quoted strings can do, and interpolate to boot, what's the point of single-quoted strings? They are often useful because they are truly literal, and contain exactly the characters you type. For example, the "backslash" character is special on most systems, as in the literal newline \n. If you want a variable to contain a literal backslash, single quotes make it easier:

>>  '\n'       # Aliteral backslash n
=> "\\n"

As with the # character in our previous example, Ruby needs to escape the backslash with an additional backslash; inside double-quoted strings, a literal backslash is represented with two backslashes.

For a small example like this, there's not much savings, but if there are lots of things to escape it can be a real help:

>>  'Newlines (\n) and tabs (\t) both use the backslash character \.'
=> "Newlines (\\n) and tabs (\\t) both use the backslash character \\."

4.2.3 Objects and Message Passing

Everything in Ruby, including strings and even nil , is an object. We'll see the technical meaning of this in Section 4.4.2, but I don't think anyone ever understood objects by reading the definition in a book; you have to build up your intuition for objects by seeing lots of examples.

It's easier to describe what objects do, which is respond to messages. An object like a string, for example, can respond to the message length, which returns the number of characters in the string:

>> "foobar".length       # Passing the "length" message to a string
=> 6

Typically, the messages that get passed to objects are methods, which are functions defined on those objects.7 Strings also respond to the empty? method:

>> "foobar".empty?
=> false
>> "".empty?
=> true

Note the question mark at the end of the empty? method. This is a Ruby convention indicating that the return value is boolean: true or false. Booleans are especially useful for control flow:

>> s = "foobar"
>> if s.empty?
>>   "The string is empty"
>> else
>>   "The string is nonempty"
>> end
=> "The string is nonempty"

Booleans can also be combined using the && ("and"), || ("or"), and ! ("not") operators:

>> x = "foo"
=> "foo"
>> y =""
=> ""
>> puts "Both strings are empty" if x.empty? && y.empty?
=> nil
>> puts "One of the strings is empty" if x.empty? || y.empty?
"One of the strings is empty"
=> nil
>> puts "x is not empty" if !x.empty?
=> "x is not empty"

Since everything in Ruby is an object, it follows that nil is an object, so it, too, can respond to methods. One example is the to_s method that can convert virtually any object to a string:

>> nil.to_s
""

This certainly appears to be an empty string, as we can verify by chaining the messages we pass to nil :

>> nil.empty?
NoMethodError: You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.empty?
>> nil.to_s.empty?      # Message chaining
true

We see here that the nil object doesn't itself respond to the empty? method, but nil.to_s does.

There's a special method for testing for nil -ness, which you might be able to guess:

>> "foo".nil?
=> false
>> "".nil?
=> false
>> nil.nil?
=> true

If you look back at Listing 4.2, you'll see that the title helper tests to see if @title is nil using the nil? method. This is a hint that there's something special about instance variables (variables with an @ sign), which can best be understood by contrasting them with ordinary variables. For example, suppose we enter title and @title variables at the console without defining them first:

>> title        # Oops! We haven't defined a title variable.
NameError: undefined local variable or method 'title'
>> @title       #An instance variable in the console
=> nil
>> puts "There is no such instance variable." if @title.nil?
There is no such instance variable.
=> nil
>> "#{@title}"  # Interpolating @title when it's nil
""

You can see from this example that Ruby complains if we try to evaluate an undefined local variable, but issues no such complaint for an instance variable; instead, instance variables are nil if not defined. This code also explains why the code

Ruby on Rails Tutorial Sample App | <%= @title %>

becomes

Ruby on Rails Tutorial Sample App |

when @title is nil : Embedded Ruby inserts the string corresponding to the given variable, and the string corresponding to nil is "" .

The last example also shows an alternate use of the if keyword: Ruby allows you to write a statement that is evaluated only if the statement following if is true. There's a complementary unless keyword that works the same way:

>> string = "foobar"
>> puts "The string '#{string}' is nonempty." unless string.empty?
The string 'foobar' is nonempty.
=> nil

It's worth noting that the nil object is special, in that it is the only Ruby object that is false in a boolean context, apart from false itself:

>> if nil

>>   true
>> else
>>   false      # nil is false
>> end
=> false

In particular, all other Ruby objects are true, even 0:

>> if 0
>>   true      # 0 (and everything other than nil and false itself) is true
>> else
>>   false
>> end
=> true

4.2.4 Method Definitions

The console allows us to define methods the same way we did with the home action from Listing 3.5 or the title helper from Listing 4.2. (Defining methods in the console is a bit cumbersome, and ordinarily you would use a file, but it's convenient for demonstration purposes.) For example, let's define a function string_message that takes a single argument and returns a message based on whether the argument is empty or not:

>> def string_message(string)
>>   if string.empty?
>>     "It's an empty string!"
>>   else
>>     "The string is nonempty."
>>   end
>> end
=> nil
>> puts string_message("")
It's an empty string!
>> puts string_message("foobar")
The string is nonempty.

Note that Ruby functions have an implicit return, meaning they return the last statement evaluated—in this case, one of the two message strings, depending on whether the method's argument string is empty or not. Ruby also has an explicit return option; the following function is equivalent to the one above:

>> def string_message(string)
>>   return "It's an empty string!" if string.empty?
>>   return "The string is nonempty."
>> end

               

The alert reader might notice at this point that the second return here is actually unnecessary—being the last expression in the function, the string "The string is nonempty." will be returned regardless of the return keyword, but using return in both places has a pleasing symmetry to it.

4.2.5 Back to the title Helper

We are now in a position to understand the title helper from Listing 4.2:8

module ApplicationHelper
  # Return a title on a per-page basis.               # Documentation comment
  def title                                           # Method definition
    base_title = "Ruby on Rails Tutorial Sample App"  # Variable assignment
    if @title.nil?                                    # Boolean test for nil
      base_title                                      # Implicit return
    else
      "#{base_title} | #{@title}"                     # String interpolation
    end
  end
end

These elements—function definition, variable assignment, boolean tests, control flow, and string interpolation—come together to make a compact helper method for use in our site layout. The final element is module ApplicationHelper: code in Ruby modules can be mixed in to Ruby classes. When writing ordinary Ruby, you often write modules and include them explicitly yourself, but in this case Rails handles the inclusion automatically for us. The result is that the title method is automatically available in all our views.

InformIT Promotional Mailings & Special Offers

I would like to receive exclusive offers and hear about products from InformIT and its family of brands. I can unsubscribe at any time.

Overview


Pearson Education, Inc., 221 River Street, Hoboken, New Jersey 07030, (Pearson) presents this site to provide information about products and services that can be purchased through this site.

This privacy notice provides an overview of our commitment to privacy and describes how we collect, protect, use and share personal information collected through this site. Please note that other Pearson websites and online products and services have their own separate privacy policies.

Collection and Use of Information


To conduct business and deliver products and services, Pearson collects and uses personal information in several ways in connection with this site, including:

Questions and Inquiries

For inquiries and questions, we collect the inquiry or question, together with name, contact details (email address, phone number and mailing address) and any other additional information voluntarily submitted to us through a Contact Us form or an email. We use this information to address the inquiry and respond to the question.

Online Store

For orders and purchases placed through our online store on this site, we collect order details, name, institution name and address (if applicable), email address, phone number, shipping and billing addresses, credit/debit card information, shipping options and any instructions. We use this information to complete transactions, fulfill orders, communicate with individuals placing orders or visiting the online store, and for related purposes.

Surveys

Pearson may offer opportunities to provide feedback or participate in surveys, including surveys evaluating Pearson products, services or sites. Participation is voluntary. Pearson collects information requested in the survey questions and uses the information to evaluate, support, maintain and improve products, services or sites, develop new products and services, conduct educational research and for other purposes specified in the survey.

Contests and Drawings

Occasionally, we may sponsor a contest or drawing. Participation is optional. Pearson collects name, contact information and other information specified on the entry form for the contest or drawing to conduct the contest or drawing. Pearson may collect additional personal information from the winners of a contest or drawing in order to award the prize and for tax reporting purposes, as required by law.

Newsletters

If you have elected to receive email newsletters or promotional mailings and special offers but want to unsubscribe, simply email information@informit.com.

Service Announcements

On rare occasions it is necessary to send out a strictly service related announcement. For instance, if our service is temporarily suspended for maintenance we might send users an email. Generally, users may not opt-out of these communications, though they can deactivate their account information. However, these communications are not promotional in nature.

Customer Service

We communicate with users on a regular basis to provide requested services and in regard to issues relating to their account we reply via email or phone in accordance with the users' wishes when a user submits their information through our Contact Us form.

Other Collection and Use of Information


Application and System Logs

Pearson automatically collects log data to help ensure the delivery, availability and security of this site. Log data may include technical information about how a user or visitor connected to this site, such as browser type, type of computer/device, operating system, internet service provider and IP address. We use this information for support purposes and to monitor the health of the site, identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents and appropriately scale computing resources.

Web Analytics

Pearson may use third party web trend analytical services, including Google Analytics, to collect visitor information, such as IP addresses, browser types, referring pages, pages visited and time spent on a particular site. While these analytical services collect and report information on an anonymous basis, they may use cookies to gather web trend information. The information gathered may enable Pearson (but not the third party web trend services) to link information with application and system log data. Pearson uses this information for system administration and to identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents, appropriately scale computing resources and otherwise support and deliver this site and its services.

Cookies and Related Technologies

This site uses cookies and similar technologies to personalize content, measure traffic patterns, control security, track use and access of information on this site, and provide interest-based messages and advertising. Users can manage and block the use of cookies through their browser. Disabling or blocking certain cookies may limit the functionality of this site.

Do Not Track

This site currently does not respond to Do Not Track signals.

Security


Pearson uses appropriate physical, administrative and technical security measures to protect personal information from unauthorized access, use and disclosure.

Children


This site is not directed to children under the age of 13.

Marketing


Pearson may send or direct marketing communications to users, provided that

  • Pearson will not use personal information collected or processed as a K-12 school service provider for the purpose of directed or targeted advertising.
  • Such marketing is consistent with applicable law and Pearson's legal obligations.
  • Pearson will not knowingly direct or send marketing communications to an individual who has expressed a preference not to receive marketing.
  • Where required by applicable law, express or implied consent to marketing exists and has not been withdrawn.

Pearson may provide personal information to a third party service provider on a restricted basis to provide marketing solely on behalf of Pearson or an affiliate or customer for whom Pearson is a service provider. Marketing preferences may be changed at any time.

Correcting/Updating Personal Information


If a user's personally identifiable information changes (such as your postal address or email address), we provide a way to correct or update that user's personal data provided to us. This can be done on the Account page. If a user no longer desires our service and desires to delete his or her account, please contact us at customer-service@informit.com and we will process the deletion of a user's account.

Choice/Opt-out


Users can always make an informed choice as to whether they should proceed with certain services offered by InformIT. If you choose to remove yourself from our mailing list(s) simply visit the following page and uncheck any communication you no longer want to receive: www.informit.com/u.aspx.

Sale of Personal Information


Pearson does not rent or sell personal information in exchange for any payment of money.

While Pearson does not sell personal information, as defined in Nevada law, Nevada residents may email a request for no sale of their personal information to NevadaDesignatedRequest@pearson.com.

Supplemental Privacy Statement for California Residents


California residents should read our Supplemental privacy statement for California residents in conjunction with this Privacy Notice. The Supplemental privacy statement for California residents explains Pearson's commitment to comply with California law and applies to personal information of California residents collected in connection with this site and the Services.

Sharing and Disclosure


Pearson may disclose personal information, as follows:

  • As required by law.
  • With the consent of the individual (or their parent, if the individual is a minor)
  • In response to a subpoena, court order or legal process, to the extent permitted or required by law
  • To protect the security and safety of individuals, data, assets and systems, consistent with applicable law
  • In connection the sale, joint venture or other transfer of some or all of its company or assets, subject to the provisions of this Privacy Notice
  • To investigate or address actual or suspected fraud or other illegal activities
  • To exercise its legal rights, including enforcement of the Terms of Use for this site or another contract
  • To affiliated Pearson companies and other companies and organizations who perform work for Pearson and are obligated to protect the privacy of personal information consistent with this Privacy Notice
  • To a school, organization, company or government agency, where Pearson collects or processes the personal information in a school setting or on behalf of such organization, company or government agency.

Links


This web site contains links to other sites. Please be aware that we are not responsible for the privacy practices of such other sites. We encourage our users to be aware when they leave our site and to read the privacy statements of each and every web site that collects Personal Information. This privacy statement applies solely to information collected by this web site.

Requests and Contact


Please contact us about this Privacy Notice or if you have any requests or questions relating to the privacy of your personal information.

Changes to this Privacy Notice


We may revise this Privacy Notice through an updated posting. We will identify the effective date of the revision in the posting. Often, updates are made to provide greater clarity or to comply with changes in regulatory requirements. If the updates involve material changes to the collection, protection, use or disclosure of Personal Information, Pearson will provide notice of the change through a conspicuous notice on this site or other appropriate way. Continued use of the site after the effective date of a posted revision evidences acceptance. Please contact us if you have questions or concerns about the Privacy Notice or any objection to any revisions.

Last Update: November 17, 2020