Appendix A. Leftovers: The top ten topics (we didn’t cover)

image with no caption

We’ve covered a lot of ground, and you’re almost finished with this book. We’ll miss you, but before we let you go, we wouldn’t feel right about sending you out into the world without a little more preparation. We can’t possibly fit everything you’ll need to know about Ruby into these few pages... (Actually, we did include everything originally, by reducing the type point size to .00004. It all fit, but nobody could read it. So we threw most of it away.) But we’ve kept all the best bits for this Top Ten appendix.

This really is the end of the book. Except for the index, of course. (A must-read!)

#1 Other cool libraries

Ruby on Rails

Sinatra (which we covered in Chapter 14 and Chapter 15) is a great way to build simple web apps. But all apps need new features, and so they grow over time. Eventually you’ll need more than just a place to put your ERB templates. You’ll also need a place to put database configuration, a place to put JavaScript code and CSS styles, a place to put code to tie all this together, and more.

And that’s where Ruby on Rails excels: giving you standardized places to put things.

It starts with the fundamental architecture of every Rails app, which follows the popular Model, View, Controller (MVC) pattern:

  • The model is where you put data for your app. Rails can automatically save model objects to a database for you and retrieve them again later. (This is similar to the Movie and MovieStore classes we created for our Sinatra app.)

  • The view is where you put code to display model data to users. By default, Rails uses ERB templates to render HTML (or JSON, or XML) views. (Again, just like we did in our Sinatra app.)

  • The controller is where you put code to respond to browser requests. Controllers take a request, call on the model to get the appropriate data, call on the view to render an appropriate response, and send the response back to the browser.

image with no caption

Deciding where to put all this code yourself would be a daunting task. Configuring Ruby to know where to look for it all would be worse. That’s why Rails promotes “convention over configuration.” If you put code for your model, view, and controller in the standard places Rails looks, you don’t have to configure any of this. It’s all handled for you. And that’s why Rails is such a powerful (and popular) web framework!

Visit http://rubyonrails.org/ to learn more about Rails.

dRuby

dRuby, part of the Ruby standard library, is a great example of Ruby’s power. It stands for “distributed Ruby,” and it allows you to make any Ruby object network-accessible. You just create the object and tell dRuby to offer it up as a service. Then you can call methods on that object from Ruby scripts running on a completely different computer.

You don’t have to write special service code. You hardly have to write anything. It just works, because Ruby is uniquely suited to forward method calls from one object to another. (We’ll talk about that more in a bit).

Here’s a short script that makes an ordinary array available over the network. You just give dRuby the array, and specify the URL (including a port number) at which it should be made available. We’ve also added some code to repeatedly print the array, so you can watch as client programs modify it.

image with no caption

Now, here’s a separate script that acts as a client. It connects to the server script over the network, and gets an object that acts as a proxy to the remote object.

image with no caption

Any method you call on the proxy is sent over the network, and called on the remote object. Any return values are sent back over the network, and returned from the proxy.

To try this out, open a terminal window and run server.rb. It will start printing the contents of the array in my_object every 10 seconds.

Now, in a different terminal window, run client.rb. If you switch back to the first terminal, you’ll see that the client has added new values to the array!

image with no caption

Are there security concerns with this? You bet. Make sure you’re behind a firewall when using dRuby. For more information (and more cool ideas), look up dRuby in the Ruby standard library documentation.

image with no caption

CSV

If you’ve ever had an office job, you’ve probably had to work with data in spreadsheets, either yours or someone else’s. And while spreadsheets offer formulas, the syntax is limiting (and a pain to remember).

Most spreadsheet programs can export CSV format (short for Comma-Separated Values), a plain-text format where rows are separated into text lines and columns are separated by commas.

image with no caption

Ruby offers the CSV library as part of its standard library, to make processing CSV files more convenient. This short script uses CSV to print just the associate names and sales totals from the above file. It skips printing the header row, and instead lets you use the headers as keys to access column values, as if each row of the CSV file were a hash.

image with no caption

We only had room to mention these three libraries in this appendix. Look for “Ruby standard library” in a search engine to learn about the dozens of options in the standard library. And for thousands more gems, visit http://rubygems.org.

#2 Inline if and unless

We’ve said all along that Ruby helps you do more with less code. This principle is built right into the language. One example of this is inline conditionals.

You’ve already seen the regular forms of if and unless, of course:

if true
  puts "I'll be printed!"
end

unless true
  puts "I won't!"
end

But if the code within your conditional is only one line long, you have the option to move the conditional to the end of that line. These expressions work just like the ones above:

puts "I'll be printed!" if true

puts "I won't!" unless true

#3 Private methods

When you first create a class, you’ll probably be the only one using it. But that (hopefully) won’t always be the case. Other developers will find your class and realize it solves their problems, too. But their problems are not always the same as your problems, and perhaps they will use your class in ways you didn’t foresee. That’s fine, until you need to make changes to your class.

Suppose you need to add a 15% surcharge on any amount your customers are billed for. You could create an Invoice class that allows you to set a subtotal attribute. You could have a total method that calculates the total amount for the bill. And to keep the total method from getting too complex, you might break the calculation of fees out into a separate fees method, which total calls.

image with no caption

But then you learn that your department intends to add a flat $25 fee to all invoices as well. So you add a flat_rate parameter to your fees method to account for that...

image with no caption

This works great, until you get a call from another department, who want to know why your class broke their code. Evidently they started using your fees method to calculate their own 8% surcharge. But their code is still written with the assumption that fees requires two parameters, even though it’s been updated to require three!

image with no caption

The problem here is that other developers are calling your fees method from outside your class, when you really only intended for it to be called inside your class. Now you have a choice: figure out how to make the fees method work for both you and the other developers who are using it, or change it back and then never modify it again.

There’s a way to avoid this situation, though. If you know a method will only be used from inside your class, you can mark it as private. Private methods can only be called from within the class on which they’re defined. Here’s an updated version of the Invoice class, with the fees method marked private:

image with no caption

Now, code that tries to call the fees method from outside the Invoice class will receive an error indicating that the method being called is private.

image with no caption

But your total method (which is an instance method on the same class as fees) can still call it.

image with no caption

The other department will have to find a different way to calculate their fees, it’s true. But future misunderstandings of this sort will be averted. And you’ll be free to make any changes to the fees method you need! Private methods can help keep your code clean and easy to update.

#4 Command-line arguments

We like to “quote” emails that we reply to by marking them with a > character before each line of text. That way, the recipient will know what we’re talking about.

Here’s a quick script that will read in the contents of a text file and insert “>” before each line:

image with no caption

We have to go into the script and change the filename every time we want to use a new input file, though. It would be nice if we had a way to specify the filename outside of our script.

image with no caption

And we can! We just need to use command-line arguments. Programs that run in your terminal often allow you to specify arguments after the program name, much like arguments to a method call, and Ruby scripts are no exception. You can access the arguments your script was called with through the ARGV array, which is set up every time a Ruby program runs. The first argument is at ARGV[0], the second at ARGV[1], and so forth.

The two-line args_test.rb script below demonstrates this. If we run it in a terminal, whatever we type in the terminal after the script name will be printed when the script runs.

image with no caption

We can use ARGV in quote.rb to allow us to specify any input file we want, each time we run it. We just need to replace the hardcoded filename with ARGV[0]. From then on, when we run quote.rb in the terminal, we can simply specify an input filename after the script name!

image with no caption

#5 Regular expressions

Regular expressions are a way of looking for patterns within text. Many programming languages offer regular expressions, but they’re especially easy to work with in Ruby.

If you’re looking for an email address within some text, you can use a regular expression to say, “Find me some letters, followed by an @ symbol, then more letters, then a period, then more letters.”

image with no caption

If you’re looking for the end of a sentence, you can use a regular expression to say, “Find me a period, question mark, or exclamation point, followed by a space.”

image with no caption

Regular expressions are insanely powerful, but they can also be complex and hard to read. Even if you only learn their most basic features, though, you’ll still find them quite useful. Our goal here is to give you a sample of what they can do for you, and give you a couple of resources where you can learn more on your own.

Suppose you have a string, and you need to find a phone number within it:

"Tel: 555-0199"

You can create a regular expression to find it for you. Regular expression literals start and end with a forward slash (/) character.

image with no caption

A regular expression by itself doesn’t do anything, though. You can use the =~ operator in a conditional to test whether the regular expression matches your string:

image with no caption

Relax

You don’t have to know regular expressions to program in Ruby.

They’re powerful, but they’re also very complex, so they’re not used all the time. But even if you only learn the basics, they can be a big help if you’re working with a lot of strings!

Right now, our regular expression can only match one phone number: 555–0199. To match other numbers as well, we can use the d character class, which will match any digit from 0 through 9. (Other character classes include w for characters from words, and s for whitespace.)

image with no caption

Instead of typing d repeatedly like the code above, we can use a single d followed by +, which looks for one or more of the preceding match.

image with no caption

Better yet, we can use a number inside of curly braces, which indicates you expect the preceding match to occur that number of times.

image with no caption

You can record the text that your regular expression matched by using a capture group. If you place parentheses around part of your regular expression, then that part of the match will be recorded in a special variable named $1. You can print the value in $1 to see what was matched.

image with no caption

A regular expression is just another object in Ruby, so you can pass them as arguments to methods. Strings have a sub method that will look for a regular expression within a string, and substitute a new string in place of the match. This call to sub will blank out any phone numbers within the string:

image with no caption

This has been just a tiny taste of what regular expressions can do. There’s lots more functionality that we don’t have room to cover here, and you could go your entire programming career without ever fully mastering regular expressions. But if you learn the basics, they can save you a lot of time and coding!

If you want to learn more, check out the chapter on regular expressions in Programming Ruby by Dave Thomas, Chad Fowler, and Andy Hunt. (We’ll talk about that book more in a bit.) Or look up the

#6 Singleton methods

Most object-oriented languages let you define instance methods that are available on all instances of a class. But Ruby is one of the few that let you define instance methods on a single instance. Such methods are known as singleton methods.

Here we have a Person class, with one instance method, speak. When you first create an instance of Person, it only has the speak instance method available.

image with no caption

But in Ruby, it’s possible to define an instance method that is available on one single object. Following the def keyword, you include a reference to the object, a dot operator, and the name of the singleton method you want to define.

This code will define a fly method on the object in the superhero variable. The fly method can be called like any other instance method, but it will be available only on superhero.

image with no caption

It’s also possible to override methods defined by the class with singleton methods. This code overrides the speak instance method from the Person class with a version unique to the superhero:

image with no caption

This ability can be quite useful in unit tests, where you sometimes need an object’s method not to behave the way it usually does. For example, if an object always creates files to store output, and you don’t want it littering your hard drive with files each time you run a test, you can override the file creation method on the instance in your tests.

Singleton methods are surprisingly handy, and just one more example of Ruby’s flexibility!

#7 Call any method, even undefined ones

When you call an instance method that hasn’t been defined on an object, Ruby calls a method named method_missing on that object. The version of method_missing that all objects inherit from the Object class simply raises an exception:

image with no caption

But if you override method_missing in a class, you can create instances of it and call undefined methods on them, and you won’t get an exception. Not only that, you can do interesting things with these “phantom methods”...

Ruby always passes at least one argument to method_missing: the name of the method that was called, in the form of a symbol. Also, whatever method_missing returns will be treated as the return value of the phantom method. So here’s a class that will return a string with the name of any undefined method you call on it.

image with no caption

Any arguments passed to the undefined method get forwarded on to method_missing, so we can return arguments to the phantom method as well...

image with no caption

#7 Call any method, even undefined ones (continued)

Here’s a Politician class whose instances will promise to do anything you ask them to. You can call any undefined method and pass it an argument, and method_missing will print both the method name and argument.

image with no caption

It gets even better, though... Remember our dRuby code from a few pages ago, which created a proxy object that called methods on another object over the network?

image with no caption

Proxy objects in dRuby allow you to call any method on them. Since the proxy defines almost no methods of its own, those calls get forwarded to the proxy’s method_missing method. There, the name of the method you called and any arguments you provided are passed over the network to the server.

The server then calls the method on the actual object and sends any return value back over the network, where it’s returned from the proxy object’s method_missing.

image with no caption

The process is complex, but method_missing makes it as easy as calling a method on the proxy!

#8 Automating tasks with Rake

Remember back in Chapter 13, when we wanted to run unit tests on classes in our lib subdirectory, we had to add -I lib to the command line? We also had to specify the file containing the tests we wanted to run...

image with no caption

It’s a bit of a pain now, but what if our project grew and we had dozens of test files? Running them one at a time would get pretty unmanageable. And testing is just one of the tasks we have to perform on a regular basis. Eventually, we’ll need the ability to build documentation, package our project as a gem, and more.

Ruby comes with a tool called Rake that can simplify all of this for us. You can run the rake command from your terminal, and it will look for a file called “Rakefile” (with no filename extension) in your project directory. This file should contain Ruby code that sets up one or more tasks that Rake can perform for us.

Here’s a Rakefile that sets up a task to run all of our tests for us. It uses the class Rake::TestTask, which comes with Rake and is specialized for running tests. This TestTask is set to load files from the lib directory (no more need for -I lib), and to run every test file in the test directory (no need to specify test files one at a time).

image with no caption

Once a Rakefile is saved in your project directory, you can change to that directory in your terminal and run the command rake, followed by the name of the task you want to run. For our example, there’s only one task, test, so we’ll run that.

image with no caption

With that one simple command, Rake will find and run all the files in our test subdirectory!

Rake can help with more than just tests, though. There are also generic tasks that you can use to run any other sort of command you might need. Look up Rake in Ruby’s standard library documentation to learn more.

#9 Bundler

At the start of Chapter 14, we ran gem install sinatra in the terminal to download and install the Sinatra gem. That was simple enough, since we only needed one gem.

But suppose we also needed the i18n gem to help with internationalization (translation to other written languages), and the erubis gem for better ERB support. Suppose that we need to make sure we’re using an older version of i18n, because our code relies on a method that has been removed in the latest version. Suddenly installing gems doesn’t seem so simple anymore.

But as usual, there’s a tool available that can help: Bundler. Bundler allows each application on your system to have its own set of gems. It also helps you maintain those gems, ensuring the proper version of each is downloaded and installed, and preventing multiple versions of the same gem from conflicting with each other.

Bundler is not installed with Ruby; it’s distributed as a gem itself. So we first need to install it by typing gem install bundler (or sudo gem install bundler, if your system requires it) in the terminal. This will install the Bundler library, as well as a bundle command that you can run from your terminal.

image with no caption

Bundler gets the names of gems to install from a file named “Gemfile” (note the similarity to “Rakefile”) in your project folder. So, we’ll create a Gemfile now.

A Gemfile contains Ruby code just like a Rakefile does, but this file calls methods from the Bundler library. We start with a call to the method source, with the URL of the server we want to download gems from. Unless your company is running its own gem server, you’ll want to use the Ruby community’s server: 'https://rubygems.org'. Next, we call the method gem for each gem we want to install, and provide the gem name and version we want as arguments.

image with no caption

Once your Gemfile has been saved, change to your project directory in your terminal and run bundle install. Bundler will automatically download and install the particular versions of the gems that your Gemfile references.

image with no caption

After Bundler installs the gems in your Gemfile, you can proceed to reference them in your code just as if you’d installed them yourself. You need to make a little change when running your app, though: always be sure to prefix the command in your terminal with the bundle exec command.

Here’s why: if you don’t use the bundle command to run your app, then it’s running outside Bundler’s control. Even then, everything might seem fine. But part of Bundler’s job is to ensure that other gem versions on your system don’t conflict with the gems that Bundler installed. It can’t do that unless it’s running.

So, to be safe, when using Bundler, always type bundle exec when running your app (or read up on other ways to ensure your app runs within the Bundler environment). You’ll save yourself some trouble someday!

You can learn more about Bundler at: http://bundler.io/

image with no caption

#10 Other books

This is the end of this Ruby book, but it’s just the start of your Ruby journey. We want to recommend a couple of excellent books that will help you along the road.

Programming Ruby 1.9 & 2.0 (Fourth Edition)

By Dave Thomas, with Chad Fowler and Andy Hunt

The Ruby community has nicknamed this book the “Pickaxe” due to the picture of a pickaxe on its cover. It’s well known and widely used.

There are two kinds of technical books out there: tutorial books (like the one you’re holding) and reference books (like Programming Ruby). And the Pickaxe is a great reference: it covers all the topics we didn’t have room for in this book. At the back, it has documentation on all the important classes and modules from Ruby’s core and the standard library. (So you won’t need the HTML documentation if you have this.)

The Well-Grounded Rubyist (Second Edition)

By David A. Black

If you want insight into the simple elegance of Ruby’s inner workings, this is the place to get it. Did you know there’s actually no such thing as a class method in Ruby? (So-called class methods are actually just singleton methods on a class object.) Did you know classes are just modules that allow instance variables? David A. Black takes language behavior that sometimes seems complex and inconsistent, and reveals the underlying rules that will make it all click.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.129.70.185