JETZT ONLINE BESTELLEN
Add to Cart
Ruby Cookbook

First Edition September 2006
ISBN 978-0-596-52369-5
906 Seiten
EUR41.00

Weitere Informationen zu diesem Buch

Inhaltsverzeichnis | Rezensionen |


Inhaltsverzeichnis

	
Chapter 1: Strings
Inhaltsvorschau
Ruby is a programmer-friendly language. If you are already familiar with object oriented programming, Ruby should quickly become second nature. If you've struggled with learning object-oriented programming or are not familiar with it, Ruby should make more sense to you than other object-oriented languages because Ruby's methods are consistently named, concise, and generally act the way you expect.
Throughout this book, we demonstrate concepts through interactive Ruby sessions. Strings are a good place to start because not only are they a useful data type, they're easy to create and use. They provide a simple introduction to Ruby, a point of comparison between Ruby and other languages you might know, and an approachable way to introduce important Ruby concepts like duck typing (see Recipe 1.12), open classes (demonstrated in Recipe 1.10), symbols (Recipe 1.7), and even Ruby gems (Recipe 1.20).
If you use Mac OS X or a Unix environment with Ruby installed, go to your command line right now and type irb. If you're using Windows, you can download and install the One-Click Installer from http://rubyforge.org/projects/rubyinstaller/, and do the same from a command prompt (you can also run the fxri program, if that's more comfortable for you). You've now entered an interactive Ruby shell, and you can follow along with the code samples in most of this book's recipes.
Strings in Ruby are much like strings in other dynamic languages like Perl, Python and PHP. They're not too much different from strings in Java and C. Ruby strings are dynamic, mutable, and flexible. Get started with strings by typing this line into your interactive Ruby session:
	string = "My first string"
You should see some output that looks like this:
	=> "My first string"
You typed in a Ruby expression that created a string "My first string", and assigned it to the variable string. The value of that expression is just the new value of string, which is what your interactive Ruby session printed out on the right side of the arrow. Throughout this book, we'll represent this kind of interaction in the following form:
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Building a String from Parts
Inhaltsvorschau
You want to iterate over a data structure, building a string from it as you do.
There are two efficient solutions. The simplest solution is to start with an empty string, and repeatedly append substrings onto it with the << operator:
	hash = { "key1" => "val1", "key2" => "val2" }

	string = ""

	hash.each { |k,v| string << "#{k} is #{v}\n" }

	puts string

	# key1 is val1

	# key2 is val2
This variant of the simple solution is slightly more efficient, but harder to read:
	string = ""

	hash.each { |k,v| string << k << " is " << v << "\n" }
If your data structure is an array, or easily transformed into an array, it's usually more efficient to use Array#join:
	puts hash.keys.join("\n") + "\n"

	# key1

	# key2
In languages like Python and Java, it's very inefficient to build a string by starting with an empty string and adding each substring onto the end. In those languages, strings are immutable, so adding one string to another builds an entirely new string. Doing this multiple times creates a huge number of intermediary strings, each of which is only used as a stepping stone to the next string. This wastes time and memory.
In those languages, the most efficient way to build a string is always to put the substrings into an array or another mutable data structure, one that expands dynamically rather than by implicitly creating entirely new objects. Once you're done processing the substrings, you get a single string with the equivalent of Ruby's Array#join. In Java, this is the purpose of the StringBuffer class.
In Ruby, though, strings are just as mutable as arrays. Just like arrays, they can expand as needed, without using much time or memory. The fastest solution to this problem in Ruby is usually to forgo a holding array and tack the substrings directly onto a base string. Sometimes using Array#join is faster, but it's usually pretty close, and the << construction is generally easier to understand.
If efficiency is important to you, don't build a new string when you can append items onto an existing string. Constructs like str << 'a' + 'b'
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Substituting Variables into Strings
Inhaltsvorschau
You want to create a string that contains a representation of a Ruby variable or expression.
Within the string, enclose the variable or expression in curly brackets and prefix it with a hash character.
	number = 5

	"The number is #{number}."                      # => "The number is 5."

	"The number is #{5}."                           # => "The number is 5."

	"The number after #{number} is #{number.next}."

	# => "The number after 5 is 6."

	"The number prior to #{number} is #{number-1}."

	# => "The number prior to 5 is 4."

	"We're ##{number}!"                             # => "We're #5!"
When you define a string by putting it in double quotes, Ruby scans it for special substitution codes. The most common case, so common that you might not even think about it, is that Ruby substitutes a single newline character every time a string contains slash followed by the letter n ("\n").
Ruby supports more complex string substitutions as well. Any text kept within the brackets of the special marker #{} (that is, #{text in here}) is interpreted as a Ruby expression. The result of that expression is substituted into the string that gets created. If the result of the expression is not a string, Ruby calls its to_s method and uses that instead.
Once such a string is created, it is indistinguishable from a string created without using the string interpolation feature:
	"#{number}" == '5'                             # => true
You can use string interpolation to run even large chunks of Ruby code inside a string. This extreme example defines a class within a string; its result is the return value of a method defined in the class. You should never have any reason to do this, but it shows the power of this feature.
	%{Here is #{class InstantClass

	   def bar

	      "some text"

	    end

	 end

	 InstantClass.new.bar

	}.}

	# => "Here is some text."
The code run in string interpolations runs in the same context as any other Ruby code in the same location. To take the example above, the InstantClass class has now been defined like any other class, and can be used outside the string that defines it.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Substituting Variables into an Existing String
Inhaltsvorschau
You want to create a string that contains Ruby expressions or variable substitutions, without actually performing the substitutions. You plan to substitute values into the string later, possibly multiple times with different values each time.
There are two good solutions: printf-style strings, and ERB templates.
Ruby supports a printf-style string format like C's and Python's. Put printf directives into a string and it becomes a template. You can interpolate values into it later using the modulus operator:
	template = 'Oceania has always been at war with %s.'

	template % 'Eurasia'  # => "Oceania has always been at war with Eurasia."

	template % 'Eastasia' # => "Oceania has always been at war with Eastasia."



	'To 2 decimal places: %.2f' % Math::PI       # => "To 2 decimal places: 3.14"

	'Zero-padded: %.5d' % Math::PI               # => "Zero-padded: 00003"
An ERB template looks something like JSP or PHP code. Most of it is treated as a normal string, but certain control sequences are executed as Ruby code. The control sequence is replaced with either the output of the Ruby code, or the value of its last expression:
	require 'erb'



	template = ERB.new %q{Chunky <%= food %>!}

	food = "bacon"

	template.result(binding)                     # => "Chunky bacon!"

	food = "peanut butter"

	template.result(binding)                     # => "Chunky peanut butter!"
You can omit the call to Kernel#binding if you're not in an irb session:
	puts template.result

	# Chunky peanut butter!
You may recognize this format from the .rhtml files used by Rails views: they use ERB behind the scenes.
An ERB template can reference variables like food before they're defined. When you call ERB#result, or ERB#run, the template is executed according to the current values of those variables.
Like JSP and PHP code, ERB templates can contain loops and conditionals. Here's a more sophisticated template:
	template = %q{

	<% if problems.empty? %>

	  Looks like your code is clean!

	<% else %>

	  I found the following possible problems with your code:

	  <% problems.each do |problem, line| %>

	    * <%= problem %> on line <%= line %>

	  <% end %>

	<% end %>}.gsub(/^\s+/, '')

	template = ERB.new(template, nil, '<>')



	problems = [["Use of is_a? instead of duck typing", 23],

	            ["eval() is usually dangerous", 44]]

	template.run(binding)

	# I found the following possible problems with your code:

	# * Use of is_a? instead of duck typing on line 23

	# * eval() is usually dangerous on line 44



	problems = []

	template.run(binding)

	# Looks like your code is clean!
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Reversing a String by Words or Characters
Inhaltsvorschau
The letters (or words) of your string are in the wrong order.
To create a new string that contains a reversed version of your original string, use the reverse method. To reverse a string in place, use the reverse! method.
	s = ".sdrawkcab si gnirts sihT"

	s.reverse                            # => "This string is backwards."

	s                                    # => ".sdrawkcab si gnirts sihT"



	s. 

reverse!                           # => "This string is backwards."

	s                                    # => "This string is backwards."
To reverse the order of the words in a string, split the string into a list of whitespaceseparated words, then join the list back into a string.
	s = "order. wrong the in are words These"

	s.split(/(\s+)/). 

reverse!.join('')   # => "These words are in the wrong order."

	s.split(/\b/).reverse!.join('')      # => "These words are in the wrong. order"
The String#split method takes a regular expression to use as a separator. Each time the separator matches part of the string, the portion of the string before the separator goes into a list. split then resumes scanning the rest of the string. The result is a list of strings found between instances of the separator. The regular expression /(\s+)/ matches one or more whitespace characters; this splits the string on word boundaries, which works for us because we want to reverse the order of the words.
The regular expression \b matches a word boundary. This is not the same as matching whitespace, because it also matches punctuation. Note the difference in punctuation between the two final examples in the Solution.
Because the regular expression /(\s+)/ includes a set of parentheses, the separator strings themselves are included in the returned list. Therefore, when we join the strings back together, we've preserved whitespace. This example shows the difference between including the parentheses and omitting them:
	"Three little words".split(/\s+/)   # => ["Three", "little", "words"]

	"Three little words".split(/(\s+)/)

	# => ["Three", " ", "little", " ", "words"]
  • Recipe 1.9, "Processing a String One Word at a Time," has some regular expressions for alternative definitions of "word"
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Representing Unprintable Characters
Inhaltsvorschau
You need to make reference to a control character, a strange UTF-8 character, or some other character that's not on your keyboard.
Ruby gives you a number of escaping mechanisms to refer to unprintable characters. By using one of these mechanisms within a double-quoted string, you can put any binary character into the string.
You can reference any any binary character by encoding its octal representation into the format "\000", or its hexadecimal representation into the format "\x00".
	octal = "\000\001\010\020"

	octal.each_byte { |x| puts x }

	# 0

	# 1

	# 8

	# 16



	hexadecimal = "\x00\x01\x10\x20"

	hexadecimal.each_byte { |x| puts x }

	# 0

	# 1

	# 16

	# 32
This makes it possible to represent UTF-8 characters even when you can't type them or display them in your terminal. Try running this program, and then opening the generated file smiley.html in your web browser:
	open('smiley.html', 'wb') do |f|

	  f << '<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">'

	  f << "\xe2\x98\xBA"

	end
The most common unprintable characters (such as newline) have special mneumonic aliases consisting of a backslash and a letter.
	"\a" == "\x07" # => true # ASCII 0x07 = BEL (Sound system bell)

	"\b" == "\x08" # => true # ASCII 0x08 = BS (Backspace)

	"\e" == "\x1b" # => true # ASCII 0x1B = ESC (Escape)

	"\f" == "\x0c" # => true # ASCII 0x0C = FF (Form feed)

	"\n" == "\x0a" # => true # ASCII 0x0A = LF (Newline/line feed)

	"\r" == "\x0d" # => true # ASCII 0x0D = CR (Carriage return)

	"\t" == "\x09" # => true # ASCII 0x09 = HT (Tab/horizontal tab)

	"\v" == "\x0b" # => true # ASCII 0x0B = VT (Vertical tab)
Ruby stores a string as a sequence of bytes. It makes no difference whether those bytes are printable ASCII characters, binary characters, or a mix of the two.
When Ruby prints out a human-readable string representation of a binary character, it uses the character's \xxx octal representation. Characters with special \x mneumonics are printed as the mneumonic. Printable characters are output as their printable representation, even if another representation was used to create the string.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Converting Between Characters and Values
Inhaltsvorschau
You want to see the ASCII code for a character, or transform an ASCII code into a string.
To see the ASCII code for a specific character as an integer, use the ? operator:
	?a                 # => 97

	?!                 # => 33

	?\n                # => 10
To see the integer value of a particular in a string, access it as though it were an element of an array:
	'a'[0]             # => 97

	'bad sound'[1]     # => 97
To see the ASCII character corresponding to a given number, call its #chr method. This returns a string containing only one character:
	97.chr              # => "a"

	33.chr              # => "!"

	10.chr              # => "\n"

	0.chr               # => "\000"

	256.chr             # RangeError: 256 out of char range
Though not technically an array, a string acts a lot like like an array of Fixnum objects: one Fixnum for each byte in the string. Accessing a single element of the "array" yields a Fixnum for the corresponding byte: for textual strings, this is an ASCII code. Calling String#each_byte lets you iterate over the Fixnum objects that make up a string.
  • Recipe 1.8, "Processing a String One Character at a Time"
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Converting Between Strings and Symbols
Inhaltsvorschau
You want to get a string containing the label of a Ruby symbol, or get the Ruby symbol that corresponds to a given string.
To turn a symbol into a string, use Symbol#to_s, or Symbol#id2name, for which to_s is an alias.
	:a_ 

symbol.to_s                        # => "a_symbol"

	:AnotherSymbol.id2name                # => "AnotherSymbol"

	:"Yet another symbol!".to_s           # => "Yet another symbol!"
You usually reference a symbol by just typing its name. If you're given a string in code and need to get the corresponding symbol, you can use String.intern:
	:dodecahedron.object_id               # => 4565262

	symbol_name = "dodecahedron"

	symbol_name.intern                    # => :dodecahedron

	symbol_name.intern.object_id          # => 4565262
A Symbol is about the most basic Ruby object you can create. It's just a name and an internal ID. Symbols are useful becase a given symbol name refers to the same object throughout a Ruby program.
Symbols are often more efficient than strings. Two strings with the same contents are two different objects (one of the strings might be modified later on, and become different), but for any given name there is only one Symbol object. This can save both time and memory.
	"string".object_id          # => 1503030

	"string".object_id          # => 1500330

	:symbol.object_id           # => 4569358

	:symbol.object_id           # => 4569358
If you have n references to a name, you can keep all those references with only one symbol, using only one object's worth of memory. With strings, the same code would use n different objects, all containing the same data. It's also faster to compare two symbols than to compare two strings, because Ruby only has to check the object IDs.
	"string1" == "string2"       # => false

	:symbol1 == :symbol2         # => false
Finally, to quote Ruby hacker Jim Weirich on when to use a string versus a symbol:
  • If the contents (the sequence of characters) of the object are important, use a string.
  • If the identity of the object is important, use a symbol.
  • See Recipe 5.1, "Using Symbols as Hash Keys" for one use of symbols
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Processing a String One Character at a Time
Inhaltsvorschau
You want to process each character of a string individually.
If you're processing an ASCII document, then each byte corresponds to one character. Use String#each_byte to yield each byte of a string as a number, which you can turn into a one-character string:
	'foobar'.each_byte { |x| puts "#{x} = #{x.chr}" }

	# 102 = f

	# 111 = o

	# 111 = o

	# 98 = b

	# 97 = a

	# 114 = r
Use String#scan to yield each character of a string as a new one-character string:
	'foobar'.scan( /./ ) { |c| puts c }

	# f

	# o

	# o

	# b

	# a

	# r
Since a string is a sequence of bytes, you might think that the String#each method would iterate over the sequence, the way Array#each does. But String#each is actually used to split a string on a given record separator (by default, the newline):
	"foo\nbar".each { |x| puts x }

	# foo

	# bar
The string equivalent of Array#each method is actually each_byte. A string stores its characters as a sequence of Fixnum objects, and each_bytes yields that sequence.
String#each_byte is faster than String#scan, so if you're processing an ASCII file, you might want to use String#each_byte and convert to a string every number passed into the code block (as seen in the Solution).
String#scan works by applying a given regular expression to a string, and yielding each match to the code block you provide. The regular expression /./ matches every character in the string, in turn.
If you have the $KCODE variable set correctly, then the scan technique will work on UTF-8 strings as well. This is the simplest way to sneak a notion of "character" into Ruby's byte-based strings.
Here's a Ruby string containing the UTF-8 encoding of the French phrase "ça va":
	french = "\xc3\xa7a va"
Even if your terminal can't properly display the character "ç", you can see how the behavior of String#scan changes when you make the regular expression Unicodeaware, or set $KCODE so that Ruby handles all strings as UTF-8:
	french.scan(/./) { |c| puts c }

	#

	#

	# a

	#

	# v

	# a



	french.scan(/./u) { |c| puts c }

	# ç

	# a

	#

	# v

	# a



	$KCODE = 'u'

	french.scan(/./) { |c| puts c }

	# ç

	# a

	#

	# v

	# a
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Processing a String One Word at a Time
Inhaltsvorschau
You want to split a piece of text into words, and operate on each word.
First decide what you mean by "word." What separates one word from another? Only whitespace? Whitespace or punctuation? Is "johnny-come-lately" one word or three? Build a regular expression that matches a single word according to whatever definition you need (there are some samples are in the Discussion).
Then pass that regular expression into String#scan. Every word it finds, it will yield to a code block. The word_count method defined below takes a piece of text and creates a histogram of word frequencies. Its regular expression considers a "word" to be a string of Ruby identifier characters: letters, numbers, and underscores.
	class String

	  def 

word_count

	    frequencies = Hash.new(0)

	    downcase.scan(/\w+/) { |word| frequencies[word] += 1 }

	   return frequencies

	  end

	end



	%{Dogs dogs dog dog dogs.}.word_count

	# => {"dogs"=>3, "dog"=>2}

	%{"I have no shame," I said.}.word_count

	# => {"no"=>1, "shame"=>1, "have"=>1, "said"=>1, "i"=>2}
The regular expression /\w+/ is nice and simple, but you can probably do better for your application's definition of "word." You probably don't consider two words separated by an underscore to be a single word. Some English words, like "pan-fried" and "fo'c'sle", contain embedded punctuation. Here are a few more definitions of "word" in regular expression form:
	# Just like /\w+/, but doesn't consider underscore part of a word.

	/[0-9A-Za-z]/



	# Anything that's not whitespace is a word.

	/[^\S]+/



	# Accept dashes and apostrophes as parts of words.

	/[-'\w]+/



	# A pretty good heuristic for matching English words.

	/(\w+([-'.]\w+)*/
The last one deserves some explanation. It matches embedded punctuation within a word, but not at the edges. "Work-in-progress" is recognized as a single word, and "—-never—-" is recognized as the word "never" surrounded by punctuation. This regular expression can even pick out abbreviations and acronyms such as "Ph.D" and "U.N.C.L.E.", though it can't distinguish between the final period of an acronym and the period that ends a sentence. This means that "E.F.F." will be recognized as the word "E.F.F" and then a nonword period.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Changing the Case of a String
Inhaltsvorschau
Your string is in the wrong case, or no particular case at all.
The String class provides a variety of case-shifting methods:
	s = 'HELLO, I am not here. I WENT to tHe MaRKEt.'

	s. 

upcase           # => "HELLO, I AM NOT HERE. I WENT TO THE MARKET."

	s. 

downcase         # => "hello, i am not here. i went to the market."

	s.swapcase         # => "hello, i AM NOT HERE. i went TO ThE mArkeT."

	s.capitalize       # => "Hello, i am not here. i went to the market."
The upcase and downcase methods force all letters in the string to upper-or lowercase, respectively. The swapcase method transforms uppercase letters into lowercase letters and vice versa. The capitalize method makes the first character of the string uppercase, if it's a letter, and makes all other letters in the string lowercase.
All four methods have corresponding methods that modify a string in place rather than creating a new one: upcase!, downcase!, swapcase!, and capitalize!. Assuming you don't need the original string, these methods will save memory, especially if the string is large.
	un_banged = 'Hello world.'

	un_banged.upcase     # => "HELLO WORLD."

	un_banged            # => "Hello world."



	banged = 'Hello world.'

	banged.upcase!       # => "HELLO WORLD."

	banged               # => "HELLO WORLD."
To capitalize a string without lowercasing the rest of the string (for instance, because the string contains proper nouns), you can modify the first character of the string in place. This corresponds to the capitalize! method. If you want something more like capitalize, you can create a new string out of the old one.
	class String

	  def capitalize_first_letter

	    self[0].chr.capitalize + self[1, size]

	  end



	  def capitalize_first_letter!

	    unless self[0] == (c = self[0,1].upcase[0])

	      self[0] = c

	      self

	    end

	    # Return nil if no change was made, like upcase! et al.

	  end

	end



	s = 'i told Alice. She remembers now.'

	s.capitalize_first_letter        # => "I told Alice. She remembers now."

	s                                # => "i told Alice. She remembers now."

	s.capitalize_first_letter!

	s                                # => "I told Alice. She remembers now."
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Managing Whitespace
Inhaltsvorschau
Your string contains too much whitespace, not enough whitespace, or the wrong kind of whitespace.
Use strip to remove whitespace from the beginning and end of a string:
	" \tWhitespace at beginning and end. \t\n\n". 

strip
Add whitespace to one or both ends of a string with ljust, rjust, and center:
	s = "Some text."

	s. 

center(15)

	s. 

ljust(15)

	s. 

rjust(15)
Use the gsub method with a string or regular expression to make more complex changes, such as to replace one type of whitespace with another.
	#Normalize Ruby source code by replacing tabs with spaces

	rubyCode.gsub("\t", "     ")



	#Transform Windows-style newlines to Unix-style newlines

	"Line one\n\rLine two\n\r".gsub(\n\r", "\n")

	# => "Line one\nLine two\n"



	#Transform all runs of whitespace into a single space character

	"\n\rThis string\t\t\tuses\n all\tsorts\nof whitespace.".gsub(/\s+/," ")

	# => " This string uses all sorts of whitespace."
What counts as whitespace? Any of these five characters: space, tab (\t), newline (\n), linefeed (\r), and form feed (\f). The regular expression /\s/ matches any one character from that set. The strip method strips any combination of those characters from the beginning or end of a string.
In rare cases you may need to handle oddball "space" characters like backspace (\b or \010) and vertical tab (\v or \012). These are not part of the \s character group in a regular expression, so use a custom character group to catch these characters.
	" \bIt's whitespace, Jim,\vbut not as we know it.\n".gsub(/[\s\b\v]+/, " ")

	# => "It's whitespace, Jim, but not as we know it."
To remove whitespace from only one end of a string, use the lstrip or rstrip method:
	s = "   Whitespace madness! "

	s.lstrip                        # => "Whitespace madness! "

	s.rstrip                        # => "   Whitespace madness!"
The methods for adding whitespace to a string (center, ljust, and rjust) take a single argument: the total length of the string they should return, counting the original string and any added whitespace. If
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Testing Whether an Object Is String-Like
Inhaltsvorschau
You want to see whether you can treat an object as a string.
Check whether the object defines the to_str method.
	'A string'.respond_to? :to_str        # => true

	Exception.new.respond_to? :to_str     # => true

	4.respond_to? :to_str                 # => false
More generally, check whether the object defines the specific method of String you're thinking about calling. If the object defines that method, the right thing to do is usually to go ahead and call the method. This will make your code work in more places:
	def join_to_successor(s)

	  raise ArgumentError, 'No successor method!' unless s.respond_to? :succ

	  return "#{s}#{s.succ}"

	end



	join_to_successor('a')           # => "ab"	

	join_to_successor(4)             # => "45"

	join_to_successor(4.01)

	# ArgumentError: No successor method!
If I'd checked s.is_a? String instead of s.respond_to? :succ, then I wouldn't have been able to call join_to_successor on an integer.
This is the simplest example of Ruby's philosophy of "duck typing:" if an object quacks like a duck (or acts like a string), just go ahead and treat it as a duck (or a string). Whenever possible, you should treat objects according to the methods they define rather than the classes from which they inherit or the modules they include.
Calling obj.is_a? String will tell you whether an object derives from the String class, but it will overlook objects that, though intended to be used as strings, don't inherit from String.
Exceptions, for instance, are essentially strings that have extra information associated with them. But they don't subclass class name "String". Code that uses is_a? String to check for stringness will overlook the essential stringness of Exceptions. Many add-on Ruby modules define other classes that can act as strings: code that calls is_a? String will break when given an instance of one of those classes.
The idea to take to heart here is the general rule of duck typing: to see whether provided data implements a certain method, use respond_to? instead of checking the class. This lets a future user (possibly yourself!) create new classes that offer the same capability, without being tied down to the preexisting class structure. All you have to do is make the method names match up.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Getting the Parts of a String You Want
Inhaltsvorschau
You want only certain pieces of a string.
To get a substring of a string, call its slice method, or use the array index operator (that is, call the [] method). Either method accepts a Range describing which characters to retrieve, or two Fixnum arguments: the index at which to start, and the length of the substring to be extracted.
	s = 'My kingdom for a string!'

	s. 

slice(3,7)                      # => "kingdom"

	s[3,7]                            # => "kingdom"

	s[0,3]                            # => "My "

	s[11, 5]                          # => "for a"

	s[11, 17]                         # => "for a string!"
To get the first portion of a string that matches a regular expression, pass the regular expression into slice or []:
	s[/.ing/]                         # => "king"

	s[/str.*/]                        # => "string!"
To access a specific byte of a string as a Fixnum, pass only one argument (the zerobased index of the character) into String#slice or [] method. To access a specific byte as a single-character string, pass in its index and the number 1.
	s.slice(3)                        # => 107

	s[3]                              # => 107

	107.chr                           # => "k"

	s.slice(3,1)                      # => "k"

	s[3,1]                            # => "k"
To count from the end of the string instead of the beginning, use negative indexes:
	s.slice(-7,3)                     # => "str"

	s[-7,6]                           # => "string"
If the length of your proposed substring exceeds the length of the string, slice or [] will return the entire string after that point. This leads to a simple shortcut for getting the rightmost portion of a string:
	s[15…s.length]                  # => "a string!"
  • Recipe 1.9, "Processing a String One Word at a Time"
  • Recipe 1.17, "Matching Strings with Regular Expressions"
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Handling International Encodings
Inhaltsvorschau
You need to handle strings that contain nonASCII characters: probably Unicode characters encoded in UTF-8.
To use Unicode in Ruby, simply add the following to the beginning of code.
	$KCODE='u'

	require 'jcode'
You can also invoke the Ruby interpreter with arguments that do the same thing:
	$ ruby -Ku -rjcode
If you use a Unix environment, you can add the arguments to the shebang line of your Ruby application:
	#!/usr/bin/ruby -Ku -rjcode
The jcode library overrides most of the methods of String and makes them capable of handling multibyte text. The exceptions are String#length, String#count, and String#size, which are not overridden. Instead jcode defines three new methods: String#jlength, string#jcount, and String#jsize.
Consider a UTF-8 string that encodes six Unicode characters: efbca1 (A), efbca2 (B), and so on up to UTF-8 efbca6 (F):
	string = "\xef\xbc\xa1" + "\xef\xbc\xa2" + "\xef\xbc\xa3" +

	         "\xef\xbc\xa4" + "\xef\xbc\xa5" + "\xef\xbc\xa6"
The string contains 18 bytes that encode 6 characters:
	string.size                                          # => 18

	string.jsize                                         # => 6
String#count is a method that takes a strong of bytes, and counts how many times those bytes occurs in the string. String#jcount takes a string of characters and counts how many times those characters occur in the string:
	string.count "\xef\xbc\xa2"                          # => 13

	string.jcount "\xef\xbc\xa2"                         # => 1
String#count treats "\xef\xbc\xa2" as three separate bytes, and counts the number of times each of those bytes shows up in the string. String#jcount treats the same string as a single character, and looks for that character in the string, finding it only once.
	"\xef\xbc\xa2".length                                # => 3

	"\xef\xbc\xa2".jlength                               # => 1
Apart from these differences, Ruby handles most Unicode behind the scenes. Once you have your data in UTF-8 format, you really don't have to worry. Given that Ruby's creator Yukihiro Matsumoto is Japanese, it is no wonder that Ruby handles Unicode so elegantly.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Word-Wrapping Lines of Text
Inhaltsvorschau
You want to turn a string full of miscellaneous whitespace into a string formatted with linebreaks at appropriate intervals, so that the text can be displayed in a window or sent as an email.
The simplest way to add newlines to a piece of text is to use a regular expression like the following.
	def wrap(s, width=78)

	  s.gsub(/(.{1,#{width}})(\s+|\Z)/, "\\1\n")

	end



	wrap("This text is too short to be wrapped.")

	# => "This text is too short to be wrapped.\n"



	puts wrap("This text is not too short to be wrapped.", 20)

	# This text is not too

	# short to be wrapped.



	puts wrap("These ten-character columns are stifling my creativity!", 10)

	# These

	# ten-character

	# columns

	# are

	# stifling

	# my

	# creativity!
The code given in the Solution preserves the original formatting of the string, inserting additional line breaks where necessary. This works well when you want to preserve the existing formatting while squishing everything into a smaller space:
	poetry = %q{It is an ancient Mariner,

	And he stoppeth one of three.

	"By thy long beard and glittering eye,

	Now wherefore stopp'st thou me?}



	puts wrap(poetry, 20)

	# It is an ancient

	# Mariner,

	# And he stoppeth one

	# of three.

	# "By thy long beard

	# and glittering eye,

	# Now wherefore

	# stopp'st thou me?
But sometimes the existing whitespace isn't important, and preserving it makes the result look bad:
	prose = %q{I find myself alone these days, more often than not,

	watching the rain run down nearby windows. How long has it been

	raining? The newspapers now print the total, but no one reads them

	anymore.}



	puts wrap(prose, 60)

	# I find myself alone these days, more often than not,

	# watching the rain run down nearby windows. How long has it

	# been

	# raining? The newspapers now print the total, but no one

	# reads them

	# anymore.
Looks pretty ragged. In this case, we want to get replace the original newlines with new ones. The simplest way to do this is to preprocess the string with another regular expression:
	def reformat_wrapped(s, width=78)

	 s.gsub(/\s+/, " ").gsub(/(.{1,#{width}})( |\Z)/, "\\1\n")

	end
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Generating a Succession of Strings
Inhaltsvorschau
You want to iterate over a series of alphabetically-increasing strings as you would over a series of numbers.
If you know both the start and end points of your succession, you can simply create a range and use Range#each, as you would for numbers:
	('aa'..'ag').each { |x| puts x }

	# aa

	# ab

	# ac

	# ad

	# ae

	# af

	# ag
The method that generates the successor of a given string is String#succ. If you don't know the end point of your succession, you can define a generator that uses succ, and break from the generator when you're done.
	def endless_string_succession(start)

	  while true

	    yield start

	    start = start.succ

	  end

	end
This code iterates over an endless succession of strings, stopping when the last two letters are the same:
	endless_string_succession('fol') do |x|

	  puts x

	  break if x[-1] == x[-2]

	end

	# fol

	# fom

	# fon

	# foo
Imagine a string as an odometer. Each character position of the string has a separate dial, and the current odometer reading is your string. Each dial always shows the same kind of character. A dial that starts out showing a number will always show a number. A character that starts out showing an uppercase letter will always show an uppercase letter.
The string succession operation increments the odometer. It moves the rightmost dial forward one space. This might make the rightmost dial wrap around to the beginning: if that happens, the dial directly to its left is also moved forward one space. This might make that dial wrap around to the beginning, and so on:
	'89999'.succ                   # => "90000"

	'nzzzz'.succ                   # => "oaaaa"
When the leftmost dial wraps around, a new dial is added to the left of the odometer. The new dial is always of the same type as the old leftmost dial. If the old leftmost dial showed capital letters, then so will the new leftmost dial:
	'Zzz'.succ                     # => "AAaa"
Lowercase letters wrap around from "z" to "a". If the first character is a lowercase letter, then when it wraps around, an "a" is added on to the beginning of the string:
	'z'.succ                       # => "aa"

	'aa'.succ                      # =>  "ab"

	'zz'.succ                      # => "aaa"
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Matching Strings with Regular Expressions
Inhaltsvorschau
You want to know whether or not a string matches a certain pattern.
You can usually describe the pattern as a regular expression. The =~ operator tests a string against a regular expression:
	string = 'This is a 30-character string.'



	if string =~ /([0-9]+)-character/ and $1.to_i == string.length

	  "Yes, there are #$1 characters in that string."

	end

	# => "Yes, there are 30 characters in that string."
You can also use Regexp#match:
	match = Regexp.compile('([0-9]+)-character').match(string)

	if match && match[1].to_i == string.length

	  "Yes, there are #{match[1]} characters in that string."

	end

	# => "Yes, there are 30 characters in that string."
You can check a string against a series of regular expressions with a case statement:
	string = "123"



	case string

	when /^[a-zA-Z]+$/

	  "Letters"

	when /^[0-9]+$/

	  "Numbers"

	else

	  "Mixed"

	end

	# => "Numbers"
Regular expressions are a cryptic but powerful minilanguage for string matching and substring extraction. They've been around for a long time in Unix utilities like sed, but Perl was the first general-purpose programming language to include them. Now almost all modern languages have support for Perl-style regular expression.
Ruby provides several ways of initializing regular expressions. The following are all equivalent and create equivalent Regexp objects:
	/something/

	Regexp.new("something")

	Regexp.compile("something")

	%r{something}
The following modifiers are also of note.
Regexp::IGNORECASE
i
Makes matches case-insensitive.
Regexp::MULTILINE
m
Normally, a regexp matches against a single line of a string. This will cause a regexp to treat line breaks like any other character.
Regexp::EXTENDED
x
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Replacing Multiple Patterns in a Single Pass
Inhaltsvorschau
You want to perform multiple, simultaneous search-and-replace operations on a string.
Use the Regexp.union method to aggregate the regular expressions you want to match into one big regular expression that matches any of them. Pass the big regular expression into String#gsub, along with a code block that takes a MatchData object. You can detect which of your search terms actually triggered the regexp match, and choose the appropriate replacement term:
	class String

	  def mgsub(key_value_pairs=[].freeze)

	    regexp_fragments = key_value_pairs.collect { |k,v| k }

	    gsub( 

Regexp.union(*regexp_fragments)) do |match|

	      key_value_pairs.detect{|k,v| k =~ match}[1]

	    end

	  end

	end
Here's a simple example:
	"GO HOME!".mgsub([[/.*GO/i, 'Home'], [/home/i, 'is where the heart is']])

	# => "Home is where the heart is!"
This example replaces all letters with pound signs, and all pound signs with the letter P:
	"Here is number #123".mgsub([[/[a-z]/i, '#'], [/#/, 'P']])

	# => "#### ## ###### P123"
The naive solution is to simply string together multiple gsub calls. The following examples, copied from the solution, show why this is often a bad idea:
	"GO HOME!".gsub(/.*GO/i, 'Home').gsub(/home/i, 'is where the heart is')

	# => "is where the heart is is where the heart is!"



	"Here is number #123".gsub(/[a-z]/i, "#").gsub(/#/, "P")

	# => "PPPP PP PPPPPP P123"
In both cases, our replacement strings turned out to match the search term of a later gsub call. Our replacement strings were themselves subject to search-and-replace. In the first example, the conflict can be fixed by reversing the order of the substitutions. The second example shows a case where reversing the order won't help. You need to do all your replacements in a single pass over the string.
The mgsub method will take a hash, but it's safer to pass in an array of key-value pairs. This is because elements in a hash come out in no particular order, so you can't control the order of substution. Here's a demonstration of the problem:
	"between".mgsub(/ee/ => 'AA', /e/ => 'E') # Bad code

	# => "bEtwEEn"



	"between".mgsub([[/ee/, 'AA'], [/e/, 'E']]) # Good code

	# => "bEtwAAn"
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Validating an Email Address
Inhaltsvorschau
You need to see whether an email address is valid.
Here's a sampling of valid email addresses you might encounter:
	test_addresses = [ #The following are valid addresses according to RFC822.

	                   'joe@example.com', 'joe.bloggs@mail.example.com',

	                   'joe+ruby-mail@example.com', 'joe(and-mary)@example.museum',

	                   'joe@localhost',
Here are some invalid email addresses you might encounter:
	                   # Complete the list with some invalid addresses

	                   'joe', 'joe@', '@example.com',

	                   'joe@example@example.com',

	                   'joe and mary@example.com' ]
And here are some regular expressions that do an okay job of filtering out bad email addresses. The first one does very basic checking for ill-formed addresses:
	valid = '[^ @]+' # Exclude characters always invalid in email addresses

	username_and_machine = /^#{valid}@#{valid}$/



	test_addresses.collect { |i| i =~ username_and_machine }

	# => [0, 0, 0, 0, 0, nil, nil, nil, nil, nil]
The second one prohibits the use of local-network addresses like "joe@localhost". Most applications should prohibit such addresses.
	username_and_machine_with_tld = /^#{valid}@#{valid}\.#{valid}$/



	test_addresses.collect { |i| i =~ username_and_machine_with_tld }

	# => [0, 0, 0, 0, nil, nil, nil, nil, nil, nil]
However, the odds are good that you're solving the wrong problem.
Most email address validation is done with naive regular expressions like the ones given above. Unfortunately, these regular expressions are usually written too strictly, and reject many email addresses. This is a common source of frustration for people with unusual email addresses like joe(and-mary)@example.museum, or people taking advantage of special features of email, as in joe+ruby-mail@example.com. The regular expressions given above err on the opposite side: they'll accept some syntactically invalid email addresses, but they won't reject valid addresses.
Why not give a simple regular expression that always works? Because there's no such thing. The definition of the syntax is anything but simple. Perl hacker Paul Warren defined an 6343-character regular expression for Perl's Mail::RFC822::Address module, and even it needs some preprocessing to accept absolutely every allowable email address. Warren's regular expression will work unaltered in Ruby, but if you really want it, you should go online and find it, because it would be foolish to try to type it in.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Classifying Text with a Bayesian Analyzer
Inhaltsvorschau
You want to classify chunks of text by example: an email message is either spam or not spam, a joke is either funny or not funny, and so on.
Use Lucas Carlson's Classifier library, available as the classifier gem. It provides a naive Bayesian classifier, and one that implements Latent Semantic Indexing, a more advanced technique.
The interface for the naive Bayesian classifier is very straightforward. You create a Classifier::Bayes object with some classifications, and train it on text chunks whose classification is known:
	require 'rubygems'

	require 'classifier'



	classifier = Classifier::Bayes.new('Spam', 'Not spam')



	classifier.train_spam 'are you in the market for viagra? we sell viagra'

	classifier.train_not_spam 'hi there, are we still on for lunch?'
You can then feed the classifier text chunks whose classification is unknown, and have it guess:
	classifier.classify "we sell the cheapest viagra on the market"

	# => "Spam"

	classifier.classify "lunch sounds great"

	# => "Not spam"
Bayesian analysis is based on probablities. When you train the classifier, you are giving it a set of words and the classifier keeps track of how often words show up in each category. In the simple spam filter built in the Solution, the frequency hash looks like the @categories variable below:
	classifier

	# => #<Classifier::Bayes:0xb7cec7c8

	#       @categories={:"Not spam"=>

	#                      { :lunch=>1, :for=>1, :there=>1,

	#                        :"?"=>1, :still=>1, :","=>1 },

	#                    :Spam=>

	#                      { :market=>1, :for=>1, :viagra=>2, :"?"=>1, :sell=>1 }

	#                   },

	#       @total_words=12>
These hashes are used to build probability calculations. Note that since we mentioned the word "viagra" twice in spam messages, there is a 2 in the "Spam" frequency hash for that word. That makes it more spam-like than other words like "for" (which also shows up in nonspam) or "sell" (which only shows up once in spam). The classifier can apply these probabilities to previously unseen text and guess at a classification for it.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Chapter 2: Numbers
Inhaltsvorschau
Numbers are as fundamental to computing as breath is to human life. Even programs that have nothing to do with math need to count the items in a data structure, display average running times, or use numbers as a source of randomness. Ruby makes it easy to represent numbers, letting you breathe easy and tackle the harder problems of programming.
An issue that comes up when you're programming with numbers is that there are several different implementations of "number," optimized for different purposes: 32bit integers, floating-point numbers, and so on. Ruby tries to hide these details from you, but it's important to know about them because they often manifest as mysteriously incorrect calculations.
The first distinction is between small numbers and large ones. If you've used other programming languages, you probably know that you must use different data types to hold small numbers and large numbers (assuming that the language supports large numbers at all). Ruby has different classes for small numbers (Fixnum) and large numbers (Bignum), but you don't usually have to worry about the difference. When you type in a number, Ruby sees how big it is and creates an object of the appropriate class.
	1000.class                           # => Fixnum

	10000000000.class                    # => Bignum

	(2**30 - 1).class                    # => Fixnum

	(2**30).class                        # => Bignum
When you perform arithmetic, Ruby automatically does any needed conversions. You don't have to worry about the difference between small and large numbers:
	small = 1000

	big = small ** 5                     # => 1000000000000000

	big.class                            # => Bignum

	smaller = big / big                  # => 1

	smaller.class                        # => Fixnum
The other major distinction is between whole numbers (integers) and fractional numbers. Like all modern programming languages, Ruby implements the IEEE floating-point standard for representing fractional numbers. If you type a number that includes a decimal point, Ruby creates a Float object instead of a
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Parsing a Number from a String
Inhaltsvorschau
Given a string that contains some representation of a number, you want to get the corresponding integer or floating-point value.
Use String#to_i to turn a string into an integer. Use String#to_f to turn a string into a floating-point number.
	'400'.to_i                           # => 400

	'3.14'.to_f                          # => 3.14

	'1.602e-19'.to_f                     # => 1.602e-19
Unlike Perl and PHP, Ruby does not automatically make a number out of a string that contains a number. You must explicitly call a conversion method that tells Ruby how you want the string to be converted.
Along with to_i and to_f, there are other ways to convert strings into numbers. If you have a string that represents a hex or octal string, you can call String#hex or String#oct to get the decimal equivalent. This is the same as passing the base of the number into to_i:
	'405'.oct                            # => 261

	'405'.to_i(8)                        # => 261

	'405'.hex                            # => 1029

	'405'.to_i(16)                       # => 1029

	'fed'.hex                            # => 4077

	'fed'.to_i(16)                       # => 4077
If to_i, to_f, hex,or oct find a character that can't be part of the kind of number they're looking for, they stop processing the string at that character and return the number so far. If the string's first character is unusable, the result is zero.
	"13: a baker's dozen".to_i                         # => 13

	'1001 Nights'.to_i                                 # => 1001

	'The 1000 Nights and a Night'.to_i                 # => 0

	'60.50 Misc. Agricultural Equipment'.to_f          # => 60.5

	'$60.50'.to_f                                      # => 0.0

	'Feed the monster!'.hex                            # => 65261

	'I fed the monster at Canoga Park Waterslides'.hex # => 0

	'0xA2Z'.hex                                        # => 162

	'-10'.oct                                          # => -8

	'-109'.oct                                         # => -8

	'3.14'.to_i                                        # => 3
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Comparing Floating-Point Numbers
Inhaltsvorschau
Floating-point numbers are not suitable for exact comparison. Often, two numbers that should be equal are actually slightly different. The Ruby interpreter can make seemingly nonsensical assertions when floating-point numbers are involved:
	1.8 + 0.1                            # => 1.9

	1.8 + 0.1 == 1.9                     # => false

	1.8 + 0.1 > 1.9                      # => true
You want to do comparison operations approximately, so that floating-point numbers infintesimally close together can be treated equally.
You can avoid this problem altogether by using BigDecimal numbers instead of floats (see Recipe 2.3). BigDecimal numbers are completely precise, and work as well as as floats for representing numbers that are relatively small and have few decimal places: everyday numbers like the prices of fruits. But math on BigDecimal numbers is much slower than math on floats. Databases have native support for floating-point numbers, but not for BigDecimals. And floating-point numbers are simpler to create (simply type 10.2 in an interactive Ruby shell to get a Float object). BigDecimals can't totally replace floats, and when you use floats it would be nice not to have to worry about tiny differences between numbers when doing comparisons.
But how tiny is "tiny"? How large can the difference be between two numbers before they should stop being considered equal? As numbers get larger, so does the range of floating-point values that can reasonably be expected to model that number. 1.1 is probably not "approximately equal" to 1.2, but 1020 + 0.1 is probably "approximately equal" to 1020 + 0.2.
The best solution is probably to compare the relative magnitudes of large numbers, and the absolute magnitudes of small numbers. The following code accepts both two thresholds: a relative threshold and an absolute threshold. Both default to Float::EPSILON, the smallest possible difference between two Float objects. Two floats are considered approximately equal if they are within absolute_epsilon of each other, or if the difference between them is
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Representing Numbers to Arbitrary Precision
Inhaltsvorschau
You're doing high- precision arithmetic, and floating-point numbers are not precise enough.
A BigDecimal number can represent a real number to an arbitrary number of decimal places.
	require 'bigdecimal'



	BigDecimal("10").to_s                # => "0.1E2"

	BigDecimal("1000").to_s              # => "0.1E4"

	BigDecimal("1000").to_s("F")         # => "1000.0"



	BigDecimal("0.123456789").to_s       # => "0.123456789E0"
Compare how Float and BigDecimal store the same high-precision number:
	nm = "0.123456789012345678901234567890123456789"

	nm.to_f                         # => 0.123456789012346

	BigDecimal(nm).to_s

	# => "0.123456789012345678901234567890123456789E0"
BigDecimal numbers store numbers in scientific notation format. A BigDecimal consists of a sign (positive or negative), an arbitrarily large decimal fraction, and an arbitrarily large exponent. This is similar to the way floating-point numbers are stored, but a double- precision floating-point implementation like Ruby's cannot represent an exponent less than Float::MIN_EXP (–1021) or greater than Float::MAX_EXP (1024). Float objects also can't represent numbers at a greater precision than Float::EPSILON, or about 2.2*10-16.
You can use BigDecimal#split to split a BigDecimal object into the parts of its scientific-notation representation. It returns an array of four numbers: the sign (1 for positive numbers,–1 for negative numbers), the fraction (as a string), the base of the exponent (which is always 10), and the exponent itself.
	BigDecimal("105000").split

	# => [1, "105", 10, 6]

	# That is, 0.105*(10**6)



	BigDecimal("-0.005").split

	# => [-1, "5", 10, -2]

	# That is, -1 * (0.5*(10**-2))
A good way to test different precision settings is to create an infinitely repeating decimal like 2/3, and see how much of it gets stored. By default, BigDecimals give 16 digits of precision, roughly comparable to what a Float can give.
	(BigDecimal("2") / BigDecimal("3")).to_s

	# => "0.6666666666666667E0"



	2.0/3

	# => 0.666666666666667
You can store additional significant digits by passing in a second argument
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Representing Rational Numbers
Inhaltsvorschau
You want to precisely represent a rational number like 2/3, one that has no finite decimal expansion.
Use a Rational object; it represents a rational number as an integer numerator and denominator.
	float = 2.0/3.0                      # => 0.666666666666667

	float * 100                          # => 66.6666666666667

	float * 100 / 42                     # => 1.58730158730159



	require 'rational'

	rational = Rational(2, 3)            # => Rational(2, 3)

	rational.to_f                        # => 0.666666666666667

	rational * 100                       # => Rational(200, 3)

	rational * 100 / 42                  # => Rational(100, 63)
Rational objects can store numbers that can't be represented in any other form, and arithmetic on Rational objects is completely precise.
Since the numerator and denominator of a Rational can be Bignums, a Rational object can also represent numbers larger and smaller than those you can represent in floating-point. But math on BigDecimal objects is faster than on Rationals. BigDecimal objects are also usually easier to work with than Rationals, because most of us think of numbers in terms of their decimal expansions.
You should only use Rational objects when you need to represent rational numbers with perfect accuracy. When you do, be sure to use only Rationals, Fixnums, and Bignums in your calculations. Don't use any BigDecimals or floating-point numbers: arithmetic operations between a Rational and those types will return floating-point numbers, and you'll have lost precision forever.
	10 + Rational(2,3)                   # => Rational(32, 3)

	require 'bigdecimal'

	BigDecimal('10') + Rational(2,3)     # => 10.6666666666667
The methods in Ruby's Math module implement operations like square root, which usually give irrational results. When you pass a Rational number into one of the methods in the Math module, you get a floating-point number back:
	Math::sqrt(Rational(2,3))            # => 0.816496580927726

	Math::sqrt(Rational(25,1))           # => 5.0 

	Math::log10(Rational(100, 1))        # => 2.0
The mathn library adds miscellaneous functionality to Ruby's math functions. Among other things, it modifies the
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Generating Random Numbers
Inhaltsvorschau
You want to generate pseudorandom numbers, select items from a data structure at random, or repeatedly generate the same "random" numbers for testing purposes.
Use the Kernel#rand function with no arguments to select a psuedorandom floating-point number from a uniform distribution between 0 and 1.
	rand                                 # => 0.517297883846589

	rand                                 # => 0.946962603814814
Pass in a single integer argument n to Kernel#rand, and it returns an integer between 0 and n–1:
	rand(5)                              # => 0

	rand(5)                              # => 4

	rand(5)                              # => 3

	rand(1000)                           # => 39
You can use the single-argument form of Kernel#rand to build many common tasks based on randomness. For instance, this code selects a random item from an array.
	a = ['item1', 'item2', 'item3']

	a[rand(a.size)]                      # => "item3"
To select a random key or value from a hash, turn the keys or values into an array and select one at random.
	m = { :key1 => 'value1',

	      :key2 => 'value2', 

	      :key3 => 'value3' }

	values = m.values

	values[rand(values.size)]            # => "value1"
This code generates pronounceable nonsense words:
	def random_word 

	 letters = { ?v => 'aeiou',

	             ?c => 'bcdfghjklmnprstvwyz' }

	 word = '' 

	 'cvcvcvc'.each_byte do |x| 

	   source = letters[x]

	   word << source[rand(source.length)].chr

	 end

	 return word

	end



	random_word                          # => "josuyip" 

	random_word                          # => "haramic"
The Ruby interpreter initializes its random number generator on startup, using a seed derived from the current time and the process number. To reliably generate the same random numbers over and over again, you can set the random number seed manually by calling the Kernel#srand function with the integer argument of your choice. This is useful when you're writing automated tests of "random" functionality:
	#Some random numbers based on process number and current time

	rand(1000)                           # => 187

	rand(1000)                           # => 551

	rand(1000)                           # => 911



	#Start the seed with the number 1

	srand 1

	rand(1000)                           # => 37 

	rand(1000)                           # => 235

	rand(1000)                           # => 908



	#Reset the seed to its previous state

	srand 1

	rand(1000)                           # => 37 

	rand(1000)                           # => 235

	rand(1000)                           # => 908
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Converting Between Numeric Bases
Inhaltsvorschau
You want to convert numbers from one base to another.
You can convert specific binary, octal, or hexadecimal numbers to decimal by representing them with the 0b, 0o, or 0x prefixes:
	0b100                                # => 4

	0o100                                # => 64

	0x100                                # => 256
You can also convert between decimal numbers and string representations of those numbers in any base from 2 to 36. Simply pass the base into String#to_i or Integer#to_s.
Here are some conversions between string representations of numbers in various bases, and the corresponding decimal numbers:
	"1045".to_i(10)                      # => 1045

	"-1001001".to_i(2)                   # => -73

	"abc".to_i(16)                       # => 2748

	"abc".to_i(20)                       # => 4232

	"number".to_i(36)                    # => 1442151747

	"zz1z".to_i(36)                      # => 1678391

	"abcdef".to_i(16)                    # => 11259375

	"AbCdEf".to_i(16)                    # => 11259375
Here are some reverse conversions of decimal numbers to the strings that represent those numbers in various bases:
	42.to_s(10)                          # => "42"

	-100.to_s(2)                         # => "-1100100"

	255.to_s(16)                         # => "ff"

	1442151747.to_s(36)                  # => "number"
Some invalid conversions:
	"6".to_i(2)                          # => 0

	"0".to_i(1)                          # ArgumentError: illegal radix 1

	40.to_s(37)                          # ArgumentError: illegal radix 37
String#to_i can parse and Integer#to_s can create a string representation in every common integer base: from binary (the familiar base 2, which uses only the digits 0 and 1) to hexatridecimal (base 36). Hexatridecimal uses the digits 0–9 and the letters a–z; it's sometimes used to generate alphanumeric mneumonics for long numbers.
The only commonly used counting systems with bases higher than 36 are the variants of base-64 encoding used in applications like MIME mail attachments. These usually encode strings, not numbers; to encode a string in MIME-style base-64, use the
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Taking Logarithms
Inhaltsvorschau
You want to take the logarithm of a number, possibly a huge one.
Math.log calculates the natural log of a number: that is, the log base e.
	Math.log(1)                          # => 0.0

	Math.log(Math::E)                    # => 1.0

	Math.log(10)                         # => 2.30258509299405

	Math::E ** Math.log(25)              # => 25.0
Math.log10 calculates the log base 10 of a number:
	Math.log10(1)                          # => 0.0

	Math.log10(10)                         # => 1.0 

	Math.log10(10.1)                       # => 1.00432137378264 

	Math.log10(1000)                       # => 3.0

	10 ** Math.log10(25)                   # => 25.0
To calculate a logarithm in some other base, use the fact that, for any bases b1 and b2 , logb1(x) = logb2(x) / logb2(k).
	module Math

	  def Math.logb(num, base)

	    log(num) / log(base)

	  end

	end
A logarithm function inverts an exponentiation function. The log base k of x,or logk(x), is the number that gives x when raised to the k power. That is, Math. log10(1000)==3.0 because 10 cubed is 1000.Math.log(Math::E)==1 because e to the first power is e.
The logarithm functions for all numeric bases are related (you can get from one base to another by dividing by a constant factor), but they're used for different purposes.
Scientific applications often use the natural log: this is the fastest log implementation in Ruby. The log base 10 is often used to visualize datasets that span many orders of magnitude, such as the pH scale for acidity and the Richter scale for earthquake intensity. Analyses of algorithms often use the log base 2, or binary logarithm.
If you intend to do a lot of algorithms in a base that Ruby doesn't support natively, you can speed up the calculation by precalculating the dividend:
	dividend = Math.log(2)

	(1..6).collect { |x| Math.log(x) / dividend }

	# => [0.0, 1.0, 1.58496250072116, 2.0, 2.32192809488736, 2.58496250072116]
The logarithm functions in Math will only accept integers or floating-point numbers, not BigDecimal or Bignum
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Finding Mean, Median, and Mode
Inhaltsvorschau
You want to find the average of an array of numbers: its mean, median, or mode.
Usually when people speak of the "average" of a set of numbers they're referring to its mean, or arithmetic mean. The mean is the sum of the elements divided by the number of elements.
	def mean(array)

	  array.inject(array.inject(0) { |sum, x| sum += x } / array.size.to_f

	end



	mean([1,2,3,4])                      # => 2.5

	mean([100,100,100,100.1])            # => 100.025

	mean([-100, 100])                    # => 0.0

	mean([3,3,3,3])                      # => 3.00
The median is the item x such that half the items in the array are greater than x and the other half are less than x. Consider a sorted array: if it contains an odd number of elements, the median is the one in the middle. If the array contains an even number of elements, the median is defined as the mean of the two middle elements.
	def median(array, already_sorted=false)

	  return nil if array.empty?

	  array = array.sort unless already_sorted

	  m_pos = array.size / 2

	  return array.size % 2 == 1 ? array[m_pos] : mean(array[m_pos-1..m_pos])

	end



	median([1,2,3,4,5])                  # => 3

	median([5,3,2,1,4])                  # => 3

	median([1,2,3,4])                    # => 2.5

	median([1,1,2,3,4])                  # => 2

	median([2,3,-100,100])               # => 2.5

	median([1, 1, 10, 100, 1000])        # => 10
The mode is the single most popular item in the array. If a list contains no repeated items, it is not considered to have a mode. If an array contains multiple items at the maximum frequency, it is "multimodal." Depending on your application, you might handle each mode separately, or you might just pick one arbitrarily.
	def modes(array, find_all=true)

	  histogram = array.inject(Hash.new(0)) { |h, n| h[n] += 1; h }

	  modes = nil

	  histogram.each_pair do |item, times|

	    modes << item if modes && times == modes[0] and find_all

	    modes = [times, item] if (!modes && times>1) or (modes && times>modes[0])

	  end

	  return modes ? modes[1…modes.size] : modes

	end



	modes([1,2,3,4])                     # => nil

	modes([1,1,2,3,4])                   # => [1]

	modes([1,1,2,2,3,4])                 # => [1, 2]

	modes([1,1,2,2,3,4,4])               # => [1, 2, 4]

	modes([1,1,2,2,3,4,4], false)        # => [1]

	modes([1,1,2,2,3,4,4,4,4,4])         # => [4]
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Converting Between Degrees and Radians
Inhaltsvorschau
The trigonometry functions in Ruby's Math library take input in radians (2π radians in a circle). Most real-world applications measure angles in degrees (360 degrees in a circle). You want an easy way to do trigonometry with degrees.
The simplest solution is to define a conversion method in Numeric that will convert a number of degrees into radians.
	class Numeric

	  def degrees

	    self * Math::PI / 180 

	  end

	end
You can then treat any numeric object as a number of degrees and convert it into the corresponding number of radians, by calling its degrees method. Trigonometry on the result will work as you'd expect:
	90.degrees                           # => 1.5707963267949

	Math::tan(45.degrees)                # => 1.0

	Math::cos(90.degrees)                # => 6.12303176911189e-17

	Math::sin(90.degrees)                # => 1.0

	Math::sin(89.9.degrees)              # => 0.999998476913288



	Math::sin(45.degrees)                # => 0.707106781186547

	Math::cos(45.degrees)                # => 0.707106781186548
I named the conversion method degrees by analogy to the methods like hours defined by Rails. This makes the code easy to read, but if you look at the actual numbers, it's not obvious why 45.degrees should equal the floating-point number 0.785398163397448.
If this troubles you, you could name the method something like degrees_to_radians. Or you could use Lucas Carlson's units gem, which lets you define customized unit conversions, and tracks which unit is being used for a particular number.
	require 'rubygems' 

	require 'units/base'



	class Numeric

	  remove_method(:degrees) # Remove the implementation given in the Solution

	  add_unit_conversions(:angle => { :radians => 1, :degrees => Math::PI/180 })

	  add_unit_aliases(:angle => { :degrees => [:degree], :radians => [:radian] })

	end



	90.degrees                           # => 90.0

	90.degrees.unit                      # => :degrees

	90.degrees.to_radians                # => 1.5707963267949

	90.degrees.to_radians.unit           # => :radians



	1.degree.to_radians                  # => 0.0174532925199433

	1.radian.to_degrees                  # => 57.2957795130823
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Multiplying Matrices
Inhaltsvorschau
You want to turn arrays of arrays of numbers into mathematical matrices, and multiply the matrices together.
You can create Matrix objects from arrays of arrays, and multiply them together with the * operator:
	require ' 

matrix'

	require 'mathn'



	a1 = [[1, 1, 0, 1],

	      [2, 0, 1, 2],

	      [3, 1, 1, 2]]

	m1 =  

Matrix[*a1]

	# =>  

Matrix[[1, 1, 0, 1], [2, 0, 1, 2], [3, 1, 1, 2]]



	a2 = [[1, 0],

	      [3, 1], 

	      [1, 0], 

	      [2, 2.5]] 

	m2 = Matrix[*a2]

	# => Matrix[[1, 0], [3, 1], [1, 0], [2, 2.5]]



	m1 * m2

	# => Matrix[[6, 3.5], [7, 5.0], [11, 6.0]]
Note the unusual syntax for creating a Matrix object: you pass the rows of the matrix into the array indexing operator, not into Matrix#new (which is private).
Ruby's Matrix class overloads the arithmetic operators to support all the basic matrix arithmetic operations, including multiplication, between matrices of compatible dimension. If you perform an arithmetic operation on incompatible matrices, you'll get an ExceptionForMatrix::ErrDimensionMismatch.
Multiplying one matrix by another is simple enough, but multiplying a chain of matrices together can be faster or slower depending on the order in which you do the multiplications. This follows from the fact that multiplying a matrix with dimensions K x M, by a matrix with dimensions MxN, requires K * M * N operations and gives a matrix with dimension K * N. If K is large for some matrix, you can save time by waiting til the end before doing multiplications involving that matrix.
Consider three matrices A, B, and C, which you want to multiply together. A has 100 rows and 20 columns. B has 20 rows and 10 columns. C has 10 rows and one column.
Since matrix multiplication is associative, you'll get the same results whether you multiply A by B and then the result by C, or multiply B by C and then the result by A. But multiplying A by B requires 20,000 operations (100 * 20 * 10), and multiplying (AB) by C requires another 1,000 (100 * 10 * 1). Multiplying B by C only requires 200 operations (20 * 10 * 1), and multiplying the result by A requires 2,000 more (100 * 20 * 1). It's almost 10 times faster to multiply A(BC) instead of the naive order of (AB)C.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Solving a System of Linear Equations
Inhaltsvorschau
You have a number of linear equations (that is, equations that look like "2x + 10y + 8z = 54"), and you want to figure out the solution: the values of x, y, and z. You have as many equations as you have variables, so you can be certain of a unique solution.
Create two Matrix objects. The first Matrix should contain the coefficients of your equations (the 2, 10, and 8 of "2x + 10y + 8z = 54"), and the second should contain the constant results (the 54 of the same equation). The numbers in both matrices should be represented as floating-point numbers, rational numbers, or BigDecimal objects: anything other than plain Ruby integers.
Then invert the coefficient matrix with Matrix#inverse, and multiply the result by the matrix full of constants. The result will be a third Matrix containing the solutions to your equations.
For instance, consider these three linear equations in three variables:
	2x + 10y + 8z = 54 

	7y + 4z = 30 

	5x + 5y + 5z = 35
To solve these equations, create the two matrices:
	require 'matrix'

	require 'rational' 

	coefficients = [[2, 10, 8], [0, 7, 4], [5, 5, 5]].collect! do |row|

	  row.collect! { |x| Rational(x) }

	end

	coefficients = Matrix[*coefficients]

	# => Matrix[[Rational(2, 1), Rational(10, 1), Rational(8, 1)],

	# =>        [Rational(0, 1), Rational(7, 1), Rational(4, 1)],

	# =>        [Rational(5, 1), Rational(5, 1), Rational(5, 1)]]



	constants = Matrix[[Rational(54)], [Rational(30)], [Rational(35)]]
Take the inverse of the coefficient matrix, and multiply it by the results matrix. The result will be a matrix containing the values for your variables.
	solutions = coefficients.inverse * constants

	# => Matrix[[Rational(1, 1)], [Rational(2, 1)], [Rational(4, 1)]]
This means that, in terms of the original equations, x=1, y=2, and z=4.
This may seem like magic, but it's analagous to how you might use algebra to solve a single equation in a single variable. Such an equation looks something like Ax = B: for instance, 6x = 18. To solve for x, you divide both sides by the coefficient:
The sixes on the left side of the equation cancel out, and you can show that
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Using Complex Numbers
Inhaltsvorschau
You want to represent complex ("imaginary") numbers and perform math on them.
Use the Complex class, defined in the complex library. All mathematical and trigonometric operations are supported.
	require 'complex'



	Complex::I                      # => Complex(0, 1)



	a = Complex(1, 4)               # => Complex(1, 4)

	a.real                          # => 1

	a.image                         # => 4



	b = Complex(1.5, 4.25)          # => Complex(1.5, 4.25)

	b + 1.5                         # => Complex(3.0, 4.25)

	b + 1.5*Complex::I              # => Complex(1.5, 5.75)



	a - b                           # => Complex(-0.5, -0.25)

	a * b                           # => Complex(-15.5, 10.25)

	b.conjugate                     # => Complex(1.5, -4.25)

	Math::sin(b)                    # => Complex(34.9720129257216, 2.47902583958724)
You can use two floating-point numbers to keep track of the real and complex parts of a complex number, but that makes it complicated to do mathematical operations such as multiplication. If you were to write functions to do these operations, you'd have more or less reimplemented the Complex class. Complex simply keeps two instances of Numeric, and implements the basic math operations on them, keeping them together as a complex number. It also implements the complex-specific mathematical operation Complex#conjugate.
Complex numbers have many uses in scientific applications, but probably their coolest application is in drawing certain kinds of fractals. Here's a class that uses complex numbers to calculate and draw a character-based representation of the Mandelbrot set, scaled to whatever size your screen can handle.
	class Mandelbrot



	  # Set up the Mandelbrot generator with the basic parameters for

	  # deciding whether or not a point is in the set.



	  def initialize(bailout=10, iterations=100)

	    @bailout, @iterations = bailout, iterations

	  end
A point (x,y) on the complex plane is in the Mandelbrot set unless a certain iterative calculation tends to infinity. We can't calculate "tends towards infinity" exactly, but we can iterate the calculation a certain number of times waiting for the result to exceed some "bail-out" value.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Simulating a Subclass of Fixnum
Inhaltsvorschau
You want to create a class that acts like a subclass of Fixnum, Float, or one of Ruby's other built-in numeric classes. This wondrous class can be used in arithmetic along with real Integer or Float objects, and it will usually act like one of those objects, but it will have a different representation or implement extra functionality.
Let's take a concrete example and consider the possibilities. Suppose you wanted to create a class that acts just like Integer, except its string representation is a hexadecimal string beginning with "0x". Where a Fixnum's string representation might be "208", this class would represent 208 as "0xc8".
You could modify Integer#to_s to output a hexadecimal string. This would probably drive you insane because it would change the behavior for all Integer objects. From that point on, nearly all the numbers you use would have hexadecimal string representations. You probably want hexadecimal string representations only for a few of your numbers.
This is a job for a subclass, but you can't usefully subclass Fixnum (the Discussion explains why this is so). The only alternative is delegation. You need to create a class that contains an instance of Fixnum, and almost always delegates method calls to that instance. The only method calls it doesn't delegate should be the ones that it wants to override.
The simplest way to do this is to create a custom delegator class with the delegate library. A class created with DelegateClass accepts another object in its constructor, and delegates all methods to the corresponding methods of that object.
	require 'delegate'

	class HexNumber < DelegateClass( 

Fixnum)

	  # The string representations of this class are hexadecimal numbers

	  def to_s

	    sign = self < 0 ? "-" : ""

	    hex = abs.to_s(16)

	    "#{sign}0x#{hex}"

	  end



	  def inspect

	    to_s

	  end

	end



	HexNumber.new(10)                  # => 0xa

	HexNumber.new(-10)                 # => -0xa

	HexNumber.new(1000000)             # => 0xf4240

	HexNumber.new(1024 ** 10)          # => 0x10000000000000000000000000



	HexNumber.new(10).succ             # => 11

	HexNumber.new(10) * 2              # => 20
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Doing Math with Roman Numbers
Inhaltsvorschau
You want to convert between Arabic and Roman numbers, or do arithmetic with Roman numbers and get Roman numbers as your result.
The simplest way to define a Roman class that acts like Fixnum is to have its instances delegate most of their method calls to a real Fixnum (as seen in the previous recipe, Recipe 2.13). First we'll implement a container for the Fixnum delegate, and methods to convert between Roman and Arabic numbers:
	class Roman

	  # These arrays map all distinct substrings of Roman numbers

	  # to their Arabic equivalents, and vice versa.

	  @@roman_to_arabic = [['M', 1000], ['CM', 900], ['D', 500], ['CD', 400],

	    ['C', 100], ['XC', 90], ['L', 50], ['XL', 40], ['X', 10], ['IX', 9],

	    ['V', 5], ['IV', 4], ['I', 1]]

	  @@arabic_to_roman = @@roman_to_arabic.collect { |x| x.reverse }.reverse



	  # The Roman symbol for 5000 (a V with a bar over it) is not in

	  # ASCII nor Unicode, so we won't represent numbers larger than 3999.

	  MAX = 3999



	  def initialize(number)

	    if number.respond_to? :to_str

	      @value = Roman.to_arabic(number)

	    else

	      Roman.assert_within_range(number)

	      @value = number

	    end

	  end



	  # Raise an exception if a number is too large or small to be represented

	  # as a 

Roman number.

	  def  

Roman.assert_within_range(number)

	    unless number.between?(1, MAX)

	      msg = "#{number} can't be represented as a Roman number."

	      raise RangeError.new(msg)

	    end

	  end



	  #Find the Fixnum value of a string containing a Roman number.

	  def Roman.to_arabic(s)

	    value = s

	    if s.respond_to? :to_str

	      c = s.dup

	      value = 0

	      invalid = ArgumentError.new("Invalid Roman number: #{s}")

	      value_of_previous_number = MAX+1

	      value_from_previous_number = 0

	      @@roman_to_arabic.each_with_index do |(roman, arabic), i|

	        value_from_this_number = 0

	        while c.index(roman) == 0

	          value_from_this_number += arabic

	          if value_from_this_number >= value_of_previous_number

	            raise invalid

	          end

	          c = c[roman.size..s.size]

	        end



	        #This one's a little tricky. We reject numbers like "IVI" and

	        #"IXV", because they use the subtractive notation and then

	        #tack on a number that makes the total overshoot the number

	        #they'd have gotten without using the subtractive

	        #notation. Those numbers should be V and XIV, respectively.

	        if i > 2 and @@roman_to_arabic[i-1][0].size > 1 and

	            value_from_this_number + value_from_previous_number >=

	            @@roman_to_arabic[i-2][1]

	          raise invalid

	        end



	        value += value_from_this_number

	        value_from_previous_number = value_from_this_number

	        value_of_previous_number = arabic

	        break if c.size == 0

	      end

	      raise invalid if c.size > 0

	    end

	    return value

	  end



	  def to_arabic

	    @value

	  end

	  #Render a Fixnum as a string depiction of a  

Roman number

	  def to_ 

roman

	    value = to_arabic

	    Roman.assert_within_range(value)

	    repr = ""

	    @@arabic_to_roman.reverse_each do |arabic, roman|

	      num, value = value.divmod(arabic)

	      repr << roman * num

	    end

	    repr

	  end
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Generating a Sequence of Numbers
Inhaltsvorschau
You want to iterate over a (possibly infinite) sequence of numbers the way you can iterate over an array or a range.
Write a generator function that yields each number in the sequence.
	def fibonacci(limit = nil)

	  seed1 = 0

	  seed2 = 1

	  while not limit or seed2 <= limit

	    yield seed2

	    seed1, seed2 = seed2, seed1 + seed2

	  end

	end



	fibonacci(3) { |x| puts x }

	# 1

	# 1

	# 2

	# 3



	fibonacci(1) { |x| puts x }

	# 1

	# 1



	fibonacci { |x| break if x > 20; puts x }

	# 1

	# 1

	# 2

	# 3

	# 5

	# 8

	# 13
A generator for a sequence of numbers works just like one that iterates over an array or other data structure. The main difference is that iterations over a data structure usually have a natural stopping point, whereas most common number sequences are infinite.
One strategy is to implement a method called each that yields the entire sequence. This works especially well if the sequence is finite. If not, it's the responsibility of the code block that consumes the sequence to stop the iteration with the break keyword.
Range#each is an example of an iterator over a finite sequence, while Prime#each enumerates the infinite set of prime numbers. Range#each is implemented in C, but here's a (much slower) pure Ruby implementation for study. This code uses self.begin and self.end to call Range#begin and Range#end, because begin and end are reserved words in Ruby.
	class Range

	  def each_slow

	    x = self.begin

	    while x <= self.end

	      yield x

	      x = x.succ

	    end

	  end

	end



	(1..3).each_slow {|x| puts x} 

	# 1

	# 2

	# 3
The other kind of sequence generator iterates over a finite portion of an infinite sequence. These are methods like Fixnum#upto and Fixnum#step: they take a start and/ or an end point as input, and generate a finite sequence within those boundaries.
	class Fixnum

	  def double_upto(stop)

	    x = self

	    until x > stop

	      yield x

	    x = x * 2

	   end

	  end

	end

	10.double_upto(50) { |x| puts x }

	# 10

	# 20

	# 40
Most sequences move monotonically up or down, but it doesn't have to be that way:
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Generating Prime Numbers
Inhaltsvorschau
You want to generate a sequence of prime numbers, or find all prime numbers below a certain threshold.
Instantiate the Prime class to create a prime number generator. Call Prime#succ to get the next prime number in the sequence.
	require 'mathn' 

	primes = Prime.new 

	primes.succ                               # => 2 

	primes.succ                               # => 3
Use Prime#each to iterate over the prime numbers:
	primes.each { |x| puts x; break if x > 15; }

	# 5

	# 7

	# 11

	# 13

	# 17

	primes.succ                              # => 19
Because prime numbers are both mathematically interesting and useful in cryptographic applications, a lot of study has been lavished on them. Many algorithms have been devised for generating prime numbers and determining whether a number is prime. The code in this recipe walks a line between efficiency and ease of implementation.
The best-known prime number algorithm is the Sieve of Eratosthenes, which finds all primes in a certain range by iterating over that range multiple times. On the first pass, it eliminates every even number greater than 2, on the second pass every third number after 3, on the third pass every fifth number after 5, and so on. This implementation of the Sieve is based on a sample program packaged with the Ruby distribution:
	def sieve(max=100)

	  sieve = []

	  (2..max).each { |i| sieve[i] = i }

	  (2..Math.sqrt(max)).each do |i|

	    (i*i).step(max, i) { |j| sieve[j] = nil } if sieve[i]

	  end

	  sieve.compact

	end



	sieve(10)

	# => [2, 3, 5, 7]

	sieve(100000).size

	# => 9592
The Sieve is a fast way to find the primes smaller than a certain number, but it's memory-inefficient and it's not suitable for generating an infinite sequence of prime numbers. It's also not very compatible with the Ruby idiom of generator methods. This is where the Prime class comes in.
A Prime object stores the current state of one iteration over the set of primes. It contains all information necessary to calculate the next prime number in the sequence. Prime#each repeatedly calls Prime#succ and yields it up to whatever code block was passed in.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Checking a Credit Card Checksum
Inhaltsvorschau
You want to know whether a credit card number was entered correctly.
The last digit of every credit card is a checksum digit. You can compare the other digits against the checksum to catch mistakes someone might make when typing their credit card number.
Lucas Carlson's CreditCard library, available as the creditcard gem, contains Ruby implementations of the checksum algorithms. It adds methods to the String and Integer classes to check the internal consistency of a credit card number:
	require 'rubygems' 

	require 'creditcard'



	'5276 4400 6542 1319'.creditcard?    # => true

	'5276440065421313'.creditcard?       # => false

	1276440065421319.creditcard?         # => false
CreditCard can also determine which brand of credit card a certain number is for:
	5276440065421313.creditcard_type     # => "mastercard"
The CreditCard library uses a well-known algorithm for finding the checksum digit of a credit card. If you can't or don't want to install the creditcard gem, you can just implement the algorithm yourself:
	module CreditCard

	  def creditcard?

	    numbers = self.to_s.gsub(/[^\d]+/, '').split(//)



	    checksum = 0

	    0.upto numbers.length do |i|

	      weight = numbers[-1*(i+2)].to_i * (2 - (i%2))



	      checksum += weight % 9

	    end



	    return numbers[-1].to_i == 10 - checksum % 10

	  end

	end



	class String

	  include CreditCard

	end



	class Integer

	  include CreditCard

	end



	'5276 4400 6542 1319'.creditcard?      # => true
How does it work? First, it converts the object to an array of numbers:
	numbers = '5276 4400 6542 1319'.gsub(/[^\d]+/, '').split(//)

	# =>  ["5", "2", "7", "6", "4", "4", "0", "0",

	# =>  "6", "5", "4", "2", "1", "3", "1", "9"]
It then calculates a weight for each number based on its position, and adds that weight to a running checksum:
	checksum = 0

	0.upto numbers.length do |i|

	  weight = numbers[-1*(i+2)].to_i * (2 - (i%2))

	  checksum += weight % 9

	end

	checksum                              # => 51
If the last number of the card is equal to 10 minus the last digit of the checksum, the number is self-consistent:
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Chapter 3: Date and Time
Inhaltsvorschau
With no concept of time, our lives would be a mess. Without software programs to constantly manage and record this bizarre aspect of our universe…well, we might actually be better off. But why take the risk?
Some programs manage real-world time on behalf of the people who'd otherwise have to do it themselves: calendars, schedules, and data gatherers for scientific experiments. Other programs use the human concept of time for their own purposes: they may run experiments of their own, making decisions based on microsecond variations. Objects that have nothing to do with time are sometimes given timestamps recording when they were created or last modified. Of the basic data types, a time is the only one that directly corresponds to something in the real world.
Ruby supports the date and time interfaces you might be used to from other programming languages, but on top of them are Ruby-specific idioms that make programming easier. In this chapter, we'll show you how to use those interfaces and idioms, and how to fill in the gaps left by the language as it comes out of the box.
Ruby actually has two different time implementations. There's a set of time libraries written in C that have been around for decades. Like most modern programming languages, Ruby provides a native interface to these C libraries. The libraries are powerful, useful, and reliable, but they also have some significant shortcomings, so Ruby compensates with a second time library written in pure Ruby. The pure Ruby library isn't used for everything because it's slower than the C interface, and it lacks some of the features buried deep in the C library, such as the management of Daylight Saving Time.
The Time class contains Ruby's interface to the C libraries, and it's all you need for most applications. The Time class has a lot of Ruby idiom attached to it, but most of its methods have strange unRuby-like names like strftime and strptime. This is for the benefit of people who are already used to the C library, or one of its other interfaces (like Perl or Python's).
The internal representation of a
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Finding Today's Date
Inhaltsvorschau
You need to create an object that represents the current date and time, or a time in the future or past.
The factory method Time.now creates a Time object containing the current local time. If you want, you can then convert it to GMT time by calling Time#gmtime. The gmtime method actually modifies the underlying time object, though it doesn't follow the Ruby naming conventions for such methods (it should be called something like gmtime!).
	now = 

Time.now                    # => Sat Mar 18 16:58:07 EST 2006

	now.gmtime                        # => Sat Mar 18 21:58:07 UTC 2006



	#The original object was affected by the time zone conversion.

	now                               # => Sat Mar 18 21:58:07 UTC 2006
To create a DateTime object for the current local time, use the factory method DateTime.now. Convert a DateTime object to GMT by calling DateTime#new_offset with no argument. Unlike Time#gmtime, this method returns a second DateTime object instead of modifying the original in place.
	require 'date'

	now = DateTime.now

	# => #<DateTime: 70669826362347677/28800000000,-5/24,2299161>

	now.to_s                          # => "2006-03-18T16:58:07-0500"

	now.new_offset.to_s               # => "2006-03-18T21:58:07Z"



	#The original object was not affected by the time zone conversion.

	now.to_s                          # => "2006-03-18T16:58:07-0500"
Both Time and DateTime objects provide accessor methods for the basic ways in which the Western calendar and clock divide a moment in time. Both classes provide year, month, day, hour (in 24-hour format), min, sec, and zone accessors. Time#isdst lets you know if the underlying time of a Time object has been modified by Daylight Saving Time in its time zone. DateTime pretends Daylight Saving Time doesn't exist.
	now_time = Time.new

	now_datetime = DateTime.now

	now_time.year                      # => 2006

	now_ 

datetime.year                  # => 2006

	now_time.hour                      # => 18

	now_ 

datetime.hour                  # => 18



	now_time.zone                      # => "EST"

	now_ 

datetime.zone                  # => "-0500"

	now_time.isdst                     # => false
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Parsing Dates, Precisely or Fuzzily
Inhaltsvorschau
You want to transform a string describing a date or date/time into a Date object. You might not know the format of the string ahead of time.
The best solution is to pass the date string into Date.parse or DateTime.parse. These methods use heuristics to guess at the format of the string, and they do a pretty good job:
	require 'date'



	Date. 

parse('2/9/2007').to_s

	# => "2007-02-09"



	 

DateTime.parse('02-09-2007 12:30:44 AM').to_s

	# => "2007-09-02T00:30:44Z"



	DateTime. 

parse('02-09-2007 12:30:44 PM EST').to_s

	# => "2007-09-02T12:30:44-0500"



	 

Date.parse('Wednesday, January 10, 2001').to_s

	# => "2001-01-10"
The parse methods can save you a lot of the drudgework associated with parsing times in other programming languages, but they don't always give you the results you want. Notice in the first example how Date.parse assumed that 2/9/2007 was an American (month first) date instead of a European (day first) date. parse also tends to misinterpret two-digit years:
	Date.parse('2/9/07').to_s                   # => "0007-02-09"
Let's say that Date.parse doesn't work for you, but you know that all the dates you're processing will be formatted a certain way. You can create a format string using the standard strftime directives, and pass it along with a date string into DateTime.strptime or Date.strptime. If the date string matches up with the format string, you'll get a Date or DateTime object back. You may already be familiar with this technique, since this many languages, as well as the Unix date command, do date formatting this way.
Some common date and time formats include:
	american_date = '%m/%d/%y'

	Date.strptime('2/9/07', american_date).to_s            # => "2007-02-09"

	DateTime.strptime('2/9/05', american_date).to_s        # => "2005-02-09T00:00:00Z"

	Date.strptime('2/9/68', american_date).to_s            # => "2068-02-09"

	Date.strptime('2/9/69', american_date).to_s            # => "1969-02-09"



	european_date = '%d/%m/%y'

	Date.strptime('2/9/07', european_date).to_s            # => "2007-09-02"

	Date.strptime('02/09/68', european_date).to_s          # => "2068-09-02"

	Date.strptime('2/9/69', european_date).to_s            # => "1969-09-02"



	four_digit_year_date = '%m/%d/%Y'

	Date.strptime('2/9/2007', four_digit_year_date).to_s   # => "2007-02-09"

	Date.strptime('02/09/1968', four_digit_year_date).to_s # => "1968-02-09"

	Date.strptime('2/9/69', four_digit_year_date).to_s     # => "0069-02-09"



	date_and_time = '%m-%d-%Y %H:%M:%S %Z'

	DateTime.strptime('02-09-2007 12:30:44 EST', date_and_time).to_s

	# => "2007-02-09T12:30:44-0500"

	DateTime.strptime('02-09-2007 12:30:44 PST', date_and_time).to_s

	# => "2007-02-09T12:30:44-0800"

	DateTime.strptime('02-09-2007 12:30:44 GMT', date_and_time).to_s

	# => "2007-02-09T12:30:44Z"



	twelve_hour_clock_time = '%m-%d-%Y %I:%M:%S %p'

	DateTime.strptime('02-09-2007 12:30:44 AM', twelve_hour_clock_time).to_s

	# => "2007-02-09T00:30:44Z"

	DateTime.strptime('02-09-2007 12:30:44 PM', twelve_hour_clock_time).to_s

	# => "2007-02-09T12:30:44Z"



	word_date = '%A, %B %d, %Y'

	Date.strptime('Wednesday, January 10, 2001', word_date).to_s

	# => "2001-01-10"
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Printing a Date
Inhaltsvorschau
You want to print a date object as a string.
If you just want to look at a date, you can call Time#to_s or Date#to_s and not bother with fancy formatting:
	require 'date'

	Time.now.to_s                               # => "Sat Mar 18 19:05:50 EST 2006"

	DateTime.now.to_s                           # => "2006-03-18T19:05:50-0500"
If you need the date in a specific format, you'll need to define that format as a string containing time-format directives. Pass the format string into Time#strftime or Date#strftime. You'll get back a string in which the formatting directives have been replaced by the correpsonding parts of the Time or DateTime object.
A formatting directive looks like a percent sign and a letter: %x. Everything in a format string that's not a formatting directive is treated as a literal:
	Time.gm(2006).strftime('The year is %Y!')   # => "The year is 2006!"
The Discussion lists all the time formatting directives defined by Time#strftime and Date#strftime. Here are some common time-formatting strings, shown against a sample date of about 1:30 in the afternoon, GMT, on the last day of 2005:
	time = Time.gm(2005, 12, 31, 13, 22, 33)

	american_date = '%D'

	time.strftime(american_date)                # => "12/31/05"

	european_date = '%d/%m/%y'

	time.strftime(european_date)                # => "31/12/05"

	four_digit_year_date = '%m/%d/%Y'

	time.strftime(four_digit_year_date)         # => "12/31/2005"

	date_and_time = '%m-%d-%Y %H:%M:%S %Z'

	time.strftime(date_and_time)                # => "12-31-2005 13:22:33 GMT"

	twelve_hour_clock_time = '%m-%d-%Y %I:%M:%S %p'

	time.strftime(twelve_hour_clock_time)       # => "12-31-2005 01:22:33 PM"

	word_date = '%A, %B %d, %Y'

	time.strftime(word_date)                    # => "Saturday, December 31, 2005"
Printed forms, parsers, and people can all be very picky about the formatting of dates. Having a date in a standard format makes dates easier to read and scan for errors. Agreeing on a format also prevents ambiguities (is 4/12 the fourth of December, or the twelfth of April?)
If you require 'time', your Time objects will sprout special-purpose formatting methods for common date representation standards:
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Iterating Over Dates
Inhaltsvorschau
Given a point in time, you want to get somewhere else.
All of Ruby's time objects can be used in ranges as though they were numbers. Date and DateTime objects iterate in increments of one day, and Time objects iterate in increments of one second:
	require 'date'

	(Date.new(1776, 7, 2)..Date.new(1776, 7, 4)).each { |x| puts x }

	# 1776-07-02

	# 1776-07-03

	# 1776-07-04



	span = DateTime.new(1776, 7, 2, 1, 30, 15)..DateTime.new(1776, 7, 4, 7, 0, 0)

	span.each { |x| puts x }

	# 1776-07-02T01:30:15Z

	# 1776-07-03T01:30:15Z

	# 1776-07-04T01:30:15Z



	(Time.at(100)..Time.at(102)).each { |x| puts x }

	# Wed Dec 31 19:01:40 EST 1969

	# Wed Dec 31 19:01:41 EST 1969

	# Wed Dec 31 19:01:42 EST 1969
Ruby's Date class defines step and upto, the same convenient iterator methods used by numbers:
	the_first = Date.new(2004, 1, 1)

	the_fifth = Date.new(2004, 1, 5)



	the_first.upto(the_fifth) { |x| puts x }

	# 2004-01-01

	# 2004-01-02

	# 2004-01-03

	# 2004-01-04

	# 2004-01-05
Ruby date objects are stored internally as numbers, and a range of those objects is treated like a range of numbers. For Date and DateTime objects, the internal representation is the Julian day: iterating over a range of those objects adds one day at a time. For Time objects, the internal representation is the number of seconds since the Unix epoch: iterating over a range of Time objects adds one second at a time.
Time doesn't define the step and upto method, but it's simple to add them:
	class Time

	  def step(other_time, increment)

	   raise ArgumentError, "step can't be 0" if increment == 0

	    increasing = self < other_time

	    if (increasing && increment < 0) || (!increasing && increment > 0)

	      yield self

	      return

	      end

	      d = self

	      begin

	        yield d

	        d += increment

	      end while (increasing ? d <= other_time : d >= other_time)

	    end



	    def upto(other_time)

	      step(other_time, 1) { |x| yield x }

	    end

	  end



	  the_first = Time.local(2004, 1, 1)

	  the_second = Time.local(2004, 1, 2)

	  the_first.step(the_second, 60 * 60 * 6) { |x| puts x }

	  # Thu Jan 01 00:00:00 EST 2004

	  # Thu Jan 01 06:00:00 EST 2004

	  # Thu Jan 01 12:00:00 EST 2004

	  # Thu Jan 01 18:00:00 EST 2004

	  # Fri Jan 02 00:00:00 EST 2004



	  the_first.upto(the_first) { |x| puts x }

	  # Thu Jan 01 00:00:00 EST 2004
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Doing Date Arithmetic
Inhaltsvorschau
You want to find how much time has elapsed between two dates, or add a number to a date to get an earlier or later date.
Adding or subtracting a Time object and a number adds or subtracts that number of seconds. Adding or subtracting a Date object and a number adds or subtracts that number of days:
	require 'date'

	y2k = Time.gm(2000, 1, 1)                   # => Sat Jan 01 00:00:00 UTC 2000

	y2k + 1                                     # => Sat Jan 01 00:00:01 UTC 2000

	y2k - 1                                     # => Fri Dec 31 23:59:59 UTC 1999

	y2k + (60 * 60 * 24 * 365)                  # => Sun Dec 31 00:00:00 UTC 2000



	y2k_dt = DateTime.new(2000, 1, 1)

	(y2k_dt + 1).to_s                           # => "2000-01-02T00:00:00Z"

	(y2k_dt - 1).to_s                           # => "1999-12-31T00:00:00Z"

	(y2k_dt + 0.5).to_s                         # => "2000-01-01T12:00:00Z"

	(y2k_dt + 365).to_s                         # => "2000-12-31T00:00:00Z"
Subtracting one Time from another gives the interval between the dates, in seconds. Subtracting one Date from another gives the interval in days:
	day_one = Time.gm(1999, 12, 31)

	day_two = Time.gm(2000, 1, 1)

	day_two - day_one                           # => 86400.0

	day_one - day_two                           # => -86400.0



	day_one = DateTime.new(1999, 12, 31)

	day_two = DateTime.new(2000, 1, 1)

	day_two - day_one                           # => Rational(1, 1)

	day_one - day_two                           # => Rational(-1, 1)



	# Compare times from now and 10 seconds in the future.

	before_time = Time.now

	before_datetime = DateTime.now

	sleep(10)

	Time.now - before_time                      # => 10.003414

	DateTime.now - before_datetime              # => Rational(5001557, 43200000000)
The activesupport gem, a prerequisite of Ruby on Rails, defines many useful functions on Numeric and Time for navigating through time:
	require 'rubygems'

	require 'active_support'



	10.days.ago                                 # => Wed Mar 08 19:54:17 EST 2006

	1.month.from_now                            # => Mon Apr 17 20:54:17 EDT 2006

	2.weeks.since(Time.local(2006, 1, 1))       # => Sun Jan 15 00:00:00 EST 2006



	y2k - 1.day                                 # => Fri Dec 31 00:00:00 UTC 1999

	y2k + 6.3.years                             # => Thu Apr 20 01:48:00 UTC 2006

	6.3.years.since y2k                         # => Thu Apr 20 01:48:00 UTC 2006
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Counting the Days Since an Arbitrary Date
Inhaltsvorschau
You want to see how many days have elapsed since a particular date, or how many remain until a date in the future.
Subtract the earlier date from the later one. If you're using Time objects, the result will be a floating-point number of seconds, so divide by the number of seconds in a day:
	def last_modified(file)

	  t1 = File.stat(file).ctime

	  t2 = Time.now

	  elapsed = (t2-t1)/(60*60*24)

	  puts "#{file} was last modified #{elapsed} 

days ago."

	end

	

	last_modified("/etc/passwd")

	# /etc/passwd was last modified 125.873605469919 days ago.

	last_modified("/home/leonardr/")

	# /home/leonardr/ was last modified 0.113293513796296 days ago.
If you're using DateTime objects, the result will be a rational number. You'll probably want to convert it to an integer or floating-point number for display:
	require 'date'

	def advent_calendar(date=DateTime.now)

	  christmas = DateTime.new(date.year, 12, 25)

	  christmas = DateTime.new(date.year+1, 12, 25) if date > christmas

	  difference = (christmas-date).to_i

	  if difference == 0

	    puts "Today is Christmas."

	  else

	    puts "Only #{difference} day#{"s" unless difference==1} until Christmas."

	  end

	end



	advent_calendar(DateTime.new(2006, 12, 24))

	# Only 1 day until Christmas.

	advent_calendar(DateTime.new(2006, 12, 25))

	# Today is Christmas.

	advent_calendar(DateTime.new(2006, 12, 26))

	# Only 364 days until Christmas.
Since times are stored internally as numbers, subtracting one from another will give you a number. Since both numbers measure the same thing (time elapsed since some "time zero"), that number will actually mean something: it'll be the number of seconds or days that separate the two times on the timeline.
Of course, this works with other time intervals as well. To display a difference in hours, for Time objects divide the difference by the number of seconds in an hour (3,600, or 1.hour if you're using Rails). For DateTime objects, divide by the number of days in an hour (that is, multiply the difference by 24):
	sent = DateTime.new(2006, 10, 4, 3, 15)

	received = DateTime.new(2006, 10, 5, 16, 33)

	elapsed = (received-sent) * 24

	puts "You responded to my email #{elapsed.to_f} hours after I sent it."

	# You responded to my email 37.3 hours after I sent it.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Converting Between Time Zones
Inhaltsvorschau
You want to change a time object so that it represents the same moment of time in some other time zone.
The most common time zone conversions are the conversion of system local time to UTC, and the conversion of UTC to local time. These conversions are easy for both Time and DateTime objects.
The Time#gmtime method modifies a Time object in place, converting it to UTC. The Time#localtime method converts in the opposite direction:
	now = Time.now       # => Sat Mar 18 20:15:58 EST 2006

	now = now.gmtime               # => Sun Mar 19 01:15:58 UTC 2006

	now = now.localtime            # => Sat Mar 18 20:15:58 EST 2006
The DateTime.new_offset method converts a DateTime object from one time zone to another. You must pass in the dstination time zone's offset from UTC; to convert local time to UTC, pass in zero. Since DateTime objects are immutable, this method creates a new object identical to the old DateTime object, except for the time zone offset:
	require 'date'

	local = DateTime.now

	local.to_s                     # => "2006-03-18T20:15:58-0500"

	utc = local.new_offset(0)

	utc.to_s                       # => "2006-03-19T01:15:58Z"
To convert a UTC DateTime object to local time, you'll need to call DateTime#new_offset and pass in the numeric offset for your local time zone. The easiest way to get this offset is to call offset on a DateTime object known to be in local time. The offset will usually be a rational number with a denominator of 24:
	local = DateTime.now

	utc = local.new_offset



	local.offset                  # => Rational(-5, 24)

	local_from_utc = utc.new_offset(local.offset)

	local_from_utc.to_s           # => "2006-03-18T20:15:58-0500"

	local == local_from_utc       # => true
Time objects created with Time.at, Time.local, Time.mktime, Time.new, and Time.now are created using the current system time zone. Time objects created with Time.gm and Time.utc are created using the UTC time zone. Time objects can represent any time zone, but it's difficult to use a time zone with Time other than local time or UTC.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Checking Whether Daylight Saving Time Is in Effect
Inhaltsvorschau
You want to see whether the current time in your locale is normal time or Daylight Saving/Summer Time.
Create a Time object and check its isdst method:
	Time.local(2006, 1, 1)                 # => Sun Jan 01 00:00:00 EST 2006

	Time.local(2006, 1, 1). 

isdst           # => false

	Time.local(2006, 10, 1)                # => Sun Oct 01 00:00:00 EDT 2006

	Time.local(2006, 10, 1).isdst          # => true
Time objects representing UTC times will always return false when isdst is called, because UTC is the same year-round. Other Time objects will consult the daylight saving time rules for the time locale used to create the Time object. This is usually the sysem locale on the computer you used to create it: see Recipe 3.7 for information on changing it. The following code demonstrates some of the rules pertaining to Daylight Saving Time across the United States:
	eastern = Time.local(2006, 10, 1)      # => Sun Oct 01 00:00:00 EDT 2006

	eastern.isdst                          # => true



	ENV['TZ'] = 'US/Pacific'

	pacific = Time.local(2006, 10, 1)      # => Sun Oct 01 00:00:00 PDT 2006

	pacific.isdst                          # => true

	

	# Except for the Navajo Nation, Arizona doesn't use Daylight Saving Time.

	ENV['TZ'] = 'America/Phoenix'

	arizona = Time.local(2006, 10, 1)      # => Sun Oct 01 00:00:00 MST 2006

	arizona.isdst                          # => false



	# Finally, restore the original time zone.

	ENV['TZ'] = nil
The C library on which Ruby's Time class is based handles the complex rules for Daylight Saving Time across the history of a particular time zone or locale. For instance,
Daylight Saving Time was mandated across the U.S. in 1918, but abandoned in most locales shortly afterwards. The "zoneinfo" file used by the C library contains this information, along with many other rules:
	# Daylight saving first took effect on March 31, 1918.

	Time.local(1918, 3, 31).isdst         # => false

	Time.local(1918, 4, 1).isdst          # => true

	Time.local(1919, 4, 1).isdst          # => true



	# The federal law was repealed later in 1919, but some places

	# continued to use 

Daylight Saving Time.

	ENV['TZ'] = 'US/Pacific'

	Time.local(1920, 4, 1)                # => Thu Apr 01 00:00:00 PST 1920



	ENV['TZ'] = nil

	Time.local(1920, 4, 1)                # => Thu Apr 01 00:00:00 EDT 1920



	# Daylight Saving Time was reintroduced during the Second World War.

	Time.local(1942,2,9)                  # => Mon Feb 09 00:00:00 EST 1942

	Time.local(1942,2,10)                 # => Tue Feb 10 00:00:00 EWT 1942

	# EWT stands for "Eastern War Time"
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Converting Between Time and DateTime Objects
Inhaltsvorschau
You're working with both DateTime and Time objects, created from Ruby's two standard date/time libraries. You can't mix these objects in comparisons, iterations, or date arithmetic because they're incompatible. You want to convert all the objects into one form or another so that you can treat them all the same way.
To convert a Time object to a DateTime, you'll need some code like this:
	require 'date'

	class Time

	  def to_datetime

	    # Convert seconds + microseconds into a fractional number of seconds

	    seconds = sec + Rational(usec, 10**6)



	    # Convert a UTC offset measured in minutes to one measured in a

	    # fraction of a day.

	    offset = Rational(utc_offset, 60 * 60 * 24)

	    DateTime.new(year, month, day, hour, min, seconds, offset)

	  end

	end



	time = Time.gm(2000, 6, 4, 10, 30, 22, 4010)

	# => Sun Jun 04 10:30:22 UTC 2000

	time.to_datetime.to_s

	# => "2000-06-04T10:30:22Z"
Converting a DateTime to a Time is similar; you just need to decide whether you want the Time object to use local time or GMT. This code adds the conversion method to Date, the superclass of DateTime, so it will work on both Date and DateTime objects.
	class Date

	  def to_gm_time

	    to_time(new_offset, :gm)

	  end



	  def to_local_time

	    to_time(new_offset(DateTime.now.offset-offset), :local)

	  end



	  private

	  def to_time(dest, method)

	    #Convert a fraction of a day to a number of microseconds

	    usec = (dest.sec_fraction * 60 * 60 * 24 * (10**6)).to_i

	    Time.send(method, dest.year, dest.month, dest.day, dest.hour, dest.min,

	              dest.sec, usec)

	  end

	end



	(datetime = DateTime.new(1990, 10, 1, 22, 16, Rational(41,2))).to_s

	# => "1990-10-01T22:16:20Z"

	datetime.to_gm_time

	# => Mon Oct 01 22:16:20 UTC 1990

	datetime.to_local_time

	# => Mon Oct 01 17:16:20 EDT 1990
Ruby's two ways of representing dates and times don't coexist very well. But since neither can be a total substitute for the other, you'll probably use them both during your Ruby career. The conversion methods let you get around incompatibilities by simply converting one type to the other:
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Finding the Day of the Week
Inhaltsvorschau
You want to find the day of the week for a certain date.
Use the wday method (supported by both Time and DateTime) to find the day of the week as a number between 0 and 6. Sunday is day zero.
The following code yields to a code block the date of every Sunday between two dates. It uses wday to find the first Sunday following the start date (keeping in mind that the first date may itself be a Sunday). Then it adds seven days at a time to get subsequent Sundays:
	def every_sunday(d1, d2)

	  # You can use 1.day instead of 60*60*24 if you're using Rails.

	  one_day = d1.is_a?(Time) ? 60*60*24 : 1

	  sunday = d1 + ((7-d1.wday) % 7) * one_day

	  while sunday < d2

	    yield sunday

	    sunday += one_day * 7

	  end

	end



	def print_every_sunday(d1, d2)

	  every_sunday(d1, d2) { |sunday| puts sunday.strftime("%x")}

	end



	print_every_sunday(Time.local(2006, 1, 1), Time.local(2006, 2, 4))

	# 01/01/06

	# 01/08/06

	# 01/15/06

	# 01/22/06

	# 01/29/06
The most commonly used parts of a time are its calendar and clock readings: year, day, hour, and so on. Time and DateTime let you access these, but they also give you access to a few other aspects of a time: the Julian day of the year (yday), and, more usefully, the day of the week (wday).
The every_sunday method will accept either two Time objects or two DateTime objects. The only difference is the number you need to add to an object to increment it by one day. If you're only going to be using one kind of object, you can simplify the code a little.
To get the day of the week as an English string, use the strftime directives %A and %a:
	t = Time.local(2006, 1, 1)

	t.strftime("%A %A %A!")                    # => "Sunday Sunday Sunday!"

	t.strftime("%a %a %a!")                    # => "Sun Sun Sun!"
You can find the day of the week and the day of the year, but Ruby has no built-in method for finding the week of the year (there is a method to find the commercial week of the year; see Recipe 3.11). If you need such a method, it's not hard to create one using the day of the year and the day of the week. This code defines a
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Handling Commercial Dates
Inhaltsvorschau
When writing a business or financial application, you need to deal with commercial dates instead of civil or calendar dates.
DateTime offers some methods for working with commercial dates. Date#cwday gives the commercial day of the week, Date#cweek gives the commercial week of the year, and Date#cwyear gives the commercial year.
Consider January 1, 2006. This was the first day of calendar 2006, but since it was a Sunday, it was the last day of commercial 2005:
	require 'date'

	sunday = DateTime.new(2006, 1, 1)

	sunday.year                                # => 2006

	sunday.cwyear                              # => 2005

	sunday.cweek                               # => 52

	sunday.wday                                # => 0

	sunday.cwday                               # => 7
Commercial 2006 started on the first weekday in 2006:
	monday = sunday + 1

	monday.cwyear                              # => 2006

	monday.cweek                               # => 1
Unless you're writing an application that needs to use commercial dates, you probably don't care about this, but it's kind of interesting (if you think dates are interesting). The commercial week starts on Monday, not Sunday, because Sunday's part of the weekend. DateTime#cwday is just like DateTime#wday, except it gives Sunday a value of seven instead of zero.
This means that DateTime#cwday has a range from one to seven instead of from zero to six:
	(sunday…sunday+7).each do |d|

	  puts "#{d.strftime("%a")} #{d.wday} #{d.cwday}"

	end

	# Sun 0 7

	# Mon 1 1

	# Tue 2 2

	# Wed 3 3

	# Thu 4 4

	# Fri 5 5

	# Sat 6 6
The cweek and cwyear methods have to do with the commercial year, which starts on the first Monday of a year. Any days before the first Monday are considered part of the previous commercial year. The example given in the Solution demonstrates this: January 1, 2006 was a Sunday, so by the commercial reckoning it was part of the last week of 2005.
  • See Recipe 3.3, "Printing a Date," for the strftime directives used to print parts of commercial dates
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Running a Code Block Periodically
Inhaltsvorschau
You want to run some Ruby code (such as a call to a shell command) repeatedly at a certain interval.
Create a method that runs a code block, then sleeps until it's time to run the block again:
	def every_n_seconds(n)

	  loop do

	    before = Time.now

	    yield

	    interval = n-(Time.now-before)

	    sleep(interval) if interval > 0

	  end

	end

	every_n_seconds(5) do

	 puts "At the beep, the time will be #{Time.now.strftime("%X")}…beep!"

	end

	# At the beep, the time will be 12:21:28… beep!

	# At the beep, the time will be 12:21:33… beep!

	# At the beep, the time will be 12:21:38… beep!

	# …
There are two main times when you'd want to run some code periodically. The first is when you actually want something to happen at a particular interval: say you're appending your status to a log file every 10 seconds. The other is when you would prefer for something to happen continuously, but putting it in a tight loop would be bad for system performance. In this case, you compromise by putting some slack time in the loop so that your code isn't always running.
The implementation of every_n_seconds deducts from the sleep time the time spent running the code block. This ensures that calls to the code block are spaced evenly apart, as close to the desired interval as possible. If you tell every_n_seconds to call a code block every five seconds, but the code block takes four seconds to run, every_n_seconds only sleeps for one second. If the code block takes six seconds to run, every_n_seconds won't sleep at all: it'll come back from a call to the code block, and immediately yield to the block again.
If you always want to sleep for a certain interval, no matter how long the code block takes to run, you can simplify the code:
	def every_n_seconds(n)

	  loop do

	    yield

	    sleep(n)

	  end

	end
In most cases, you don't want every_n_seconds to take over the main loop of your program. Here's a version of every_n_seconds that spawns a separate thread to run your task. If your code block stops the loop by with the break keyword, the thread stops running:
	def every_n_seconds(n)

	  thread = Thread.new do

	    while true

	      before = Time.now

	      yield

	      interval = n-(Time.now-before)

	      sleep(interval) if interval > 0

	    end

	  end

	  return thread

	end
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Waiting a Certain Amount of Time
Inhaltsvorschau
You want to pause your program, or a single thread of it, for a specific amount of time.
The Kernel#sleep method takes a floating-point number and puts the current thread to sleep for some (possibly fractional) number of seconds:
	3.downto(1) { |i| puts "#{i}…"; sleep(1) }; puts "Go!"

	# 3…

	# 2…

	# 1…

	# Go!



	Time.new                     # => Sat Mar 18 21:17:58 EST 2006

	sleep(10)

	Time.new                     # => Sat Mar 18 21:18:08 EST 2006

	sleep(1)

	Time.new                     # => Sat Mar 18 21:18:09 EST 2006

	# Sleep for less then a second.

	Time.new.usec                # => 377185

	sleep(0.1)

	Time.new.usec                # => 479230
Timers are often used when a program needs to interact with a source much slower than a computer's CPU: a network pipe, or human eyes and hands. Rather than constantly poll for new data, a Ruby program can sleep for a fraction of a second between each poll, giving other programs on the CPU a chance to run. That's not much time by human standards, but sleeping for a fraction of a second at a time can greatly improve a system's overall performance.
You can pass any floating-point number to sleep, but that gives an exaggerated picture of how finely you can control a thread's sleeping time. For instance, you can't sleep for 10-50 seconds, because it's physically impossible (that's less than the Planck time). You can't sleep for Float::EPSILON seconds, because that's almost certainly less than the resolution of your computer's timer.
You probably can't even reliably sleep for a microsecond, even though most modern computer clocks have microsecond precision. By the time your sleep command is processed by the Ruby interpreter and the thread actually starts waiting for its timer to go off, some small amount of time has already elapsed. At very small intervals, this time can be greater than the time you asked Ruby to sleep in the first place.
Here's a simple benchmark that shows how long sleep on your system will actually make a thread sleep. It starts with a sleep interval of one second, which is fairly accurate. It then sleeps for shorter and shorter intervals, with lessening accuracy each time:
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Adding a Timeout to a Long-Running Operation
Inhaltsvorschau
You're running some code that might take a long time to complete, or might never complete at all. You want to interrupt the code if it takes too long.
Use the built-in timeout library. The Timeout.timeout method takes a code block and a deadline (in seconds). If the code block finishes running in time, it returns true. If the deadline passes and the code block is still running, Timeout.timeout terminates the code block and raises an exception.
The following code would never finish running were it not for the timeout call. But after five seconds, timeout raises a Timeout::Error and execution halts:
	# This code will sleep forever… OR WILL IT?

	require 'timeout'

	before = Time.now

	begin

	  status = Timeout.timeout(5) { sleep }

	rescue Timeout::Error

	  puts "I only slept for #{Time.now-before} seconds."

	end

	# I only slept for 5.035492 seconds.
Sometimes you must make a network connection or take some other action that might be incredibly slow, or that might never complete at all. With a timeout, you can impose an upper limit on how long that operation can take. If it fails, you can try it again later, or forge ahead without the information you were trying to get. Even when you can't recover, you can report your failure and gracefully exit the program, rather than sitting around forever waiting for the operation to complete.
By default, Timeout.timeout raises a Timeout::Error. You can pass in a custom exception class as the second argument to Timeout.timeout: this saves you from having to rescue the Timeout:Error just so you can raise some other error that your application knows how to handle.
If the code block had side effects, they will still be visible after the timeout kills the code block:
	def count_for_five_seconds

	  $counter = 0

	  begin

	    Timeout::timeout(5) { loop { $counter += 1 } }

	  rescue Timeout::Error

	    puts "I can count to #{$counter} in 5 seconds."

	  end

	end



	count_for_five_seconds

	# I can count to 2532825 in 5 seconds.

	$counter                                 # => 2532825
This may mean that your dataset is now in an inconsistent state.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Chapter 4: Arrays
Inhaltsvorschau
Like all high-level languages, Ruby has built-in support for arrays, objects that contain ordered lists of other objects. You can use arrays (often in conjunction with hashes) to build and use complex data structures without having to define any custom classes.
An array in Ruby is an ordered list of elements. Each element is a reference to some object, the way a Ruby variable is a reference to some object. For convenience, throughout this book we usually talk about arrays as though the array elements were the actual objects, not references to the objects. Since Ruby (unlike languages like C) gives no way of manipulating object references directly, the distinction rarely matters.
The simplest way to create a new array is to put a comma-separated list of object references between square brackets. The object references can be predefined variables (my_var), anonymous objects created on the spot ('my string', 4.7, or MyClass.new), or expressions (a+b, object.method). A single array can contain references to objects of many different types:
	a1 = []                              # => []

	a2 = [1, 2, 3]                       # => [1, 2, 3]

	a3 = [1, 2, 3, 'a', 'b', 'c', nil]   # => [1, 2, 3, "a", "b", "c", nil]



	n1 = 4

	n2 = 6

	sum_and_difference = [n1, n2, n1+n2, n1-n2]

	# => [4, 6, 10, -2]
If your array contains only strings, you may find it simpler to build your array by enclosing the strings in the w{} syntax, separated by whitespace. This saves you from having to write all those quotes and comma:
	%w{1 2 3}                            # => ["1", "2", "3"]

	%w{The rat sat

	   on the mat}

	# => ["The", "rat", "sat", "on", "the", "mat"]
The << operator is the simplest way to add a value to an array. Ruby dynamically resizes arrays as elements are added and removed.
	a = [1, 2, 3]                  # => [1, 2, 3]

	a << 4.0                       # => [1, 2, 3, 4.0]

	a << 'five'                    # => [1, 2, 3, 4.0, "five"]
An array element can be any object reference, including a reference to another array. An array can even contain a reference to itself, though this is usually a bad idea, since it can send your code into infinite loops.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Iterating Over an Array
Inhaltsvorschau
You want to perform some operation on each item in an array.
Iterate over the array with Enumerable#each. Put into a block the code you want to execute for each item in the array.
	[1, 2, 3, 4].each { |x| puts x }

	# 1

	# 2

	# 3

	# 4
If you want to produce a new array based on a transformation of some other array, use Enumerable#collect along with a block that takes one element and transforms it:
	[1, 2, 3, 4].collect { |x| x ** 2 }             # => [1, 4, 9, 16]
Ruby supports for loops and the other iteration constructs found in most modern programming languages, but its prefered idiom is a code block fed to an method like each or collect.
Methods like each and collect are called generators or iterators: they iterate over a data structure, yielding one element at a time to whatever code block you've attached. Once your code block completes, they continue the iteration and yield the next item in the data structure (according to whatever definition of "next" the generator supports). These methods are covered in detail in Chapter 7.
In a method like each, the return value of the code block, if any, is ignored. Methods like collect take a more active role. After they yield an element of a data structure to a code block, they use the return value in some way. The collect method uses the return value of its attached block as an element in a new array.
Although commonly used in arrays, the collect method is actually defined in the Enumerable module, which the Array class includes. Many other Ruby classes (Hash and Range are just two) include the Enumerable methods; it's a sort of baseline for Ruby objects that provide iterators. Though Enumerable does not define the each method, it must be defined by any class that includes Enumerable, so you'll see that method a lot, too. This is covered in Recipe 9.4.
If you need to have the array indexes along with the array elements, use Enumerable#each_with_index.
	['a', 'b', 'c'].each_with_index do |item, index|

	  puts "At position #{index}: #{item}"

	end

	# At position 0: a

	# At position 1: b

	# At position 2: c
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Rearranging Values Without Using Temporary Variables
Inhaltsvorschau
You want to rearrange a number of variables, or assign the elements of an array to individual variables.
Use a single assignment statement. Put the destination variables on the left-hand side, and line each one up with a variable (or expression) on the right side.
A simple swap:
	a = 1

	b = 2

	a, b = b, a

	a                                  # => 2

	b                                  # => 1
A more complex rearrangement:
	a, b, c = :red, :green, :blue

	c, a, b = a, b, c

	a                                  # => :green

	b                                  # => :blue

	c                                  # => :red
You can split out an array into its components:
	array = [:red, :green, :blue]

	c, a, b = array

	a                                  # => :green

	b                                  # => :blue

	c                                  # => :red
You can even use the splat operator to extract items from the front of the array:
	a, b, *c = [12, 14, 178, 89, 90]

	a                                   # => 12

	b                                   # => 14

	c                                   # => [178, 89, 90]
Ruby assignment statements are very versatile. When you put a comma-separated list of variables on the left-hand side of an assignment statement, it's equivalent to assigning each variable in the list the corresponding right-hand value. Not only does this make your code more compact and readable, it frees you from having to keep track of temporary variables when you swap variables.
Ruby works behind the scenes to allocate temporary storage space for variables that would otherwise be overwritten, so you don't have to do it yourself. You don't have to write this kind of code in Ruby:
	a, b = 1, 2

	x = a

	a = b

	b = x
The right-hand side of the assignment statement can get almost arbitrarily complicated:
	a, b = 5, 10

	a, b = b/a, a-1                      # => [2, 4]



	a, b, c = 'A', 'B', 'C'

	a, b, c = [a, b], { b => c }, a

	a                                    # => ["A", "B"]

	b                                    # => {"B"=>"C"}

	c                                    # => "A"
If there are more variables on the left side of the equal sign than on the right side, the extra variables on the left side get assigned
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Stripping Duplicate Elements from an Array
Inhaltsvorschau
You want to strip all duplicate elements from an array, or prevent duplicate elements from being added in the first place.
Use Array#uniq to create a new array, based on an existing array but with no duplicate elements. Array#uniq! strips duplicate elements from an existing array.
	survey_results = [1, 2, 7, 1, 1, 5, 2, 5, 1]

	distinct_answers = survey_results.uniq        # => [1, 2, 7, 5]

	survey_results.uniq!

	survey_results                                # => [1, 2, 7, 5]
To ensure that duplicate values never get into your list, use a Set instead of an array. If you try to add a duplicate element to a Set, nothing will happen.
	require 'set'

	survey_results = [1, 2, 7, 1, 1, 5, 2, 5, 1]

	distinct_answers = survey_results.to_set

	# => #<Set: {5, 1, 7, 2}>



	games = [["Alice", "Bob"], ["Carol", "Ted"],

	         ["Alice", "Mallory"], ["Ted", "Bob"]]

	players = games.inject(Set.new) { |set, game| game.each { |p| set << p }; set }

	# => #<Set: {"Alice", "Mallory", "Ted", "Carol", "Bob"}>



	players << "Ted"

	# => #<Set: {"Alice", "Mallory", "Ted", "Carol", "Bob"}>
The common element between these two solutions is the hash (see Chapter 5). Array#uniq iterates over an array, using each element as a key in a hash that it always checks to see if it encountered an element earlier in the iteration. A Set keeps the same kind of hash from the beginning, and rejects elements already in the hash. You see something that acts like an array, but it won't accept duplicates. In either case, two objects are considered "duplicates" if they have the same result for ==.
The return value of Array#uniq is itself an array, and nothing prevents you from adding duplicate elements to it later on. If you want to start enforcing uniqueness in perpetuity, you should turn the array into a Set instead of calling uniq. Requiring the set library will define a new method Enumerable#to_set, which does this.
Array#uniq preserves the original order of the array (that is, the first instance of an object remains in its original location), but a Set has no order, because its internal implementation is a hash. To get array-like order in a
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Reversing an Array
Inhaltsvorschau
Your array is the wrong way around: the last item should be first and the first should be last.
Use reverse to create a new array with the items reversed. Internal subarrays will not themselves be reversed.
	[1,2,3].reverse                           # => [3, 2, 1]

	[1,[2,3,4],5].reverse                     # => [5, [2, 3, 4], 1]
Like many operations on basic Ruby types, reverse has a corresponding method, reverse!, which reverses an array in place:
	a = [1,2,3]

	a. 

reverse!

	a                                       # => [3, 2, 1]
Don't reverse an array if you just need to iterate over it backwards. Don't use a for loop either; the reverse_each iterator is more idiomatic.
  • Recipe 1.4, " Reversing a String by Words or Characters"
  • Recipe 4.1, "Iterating Over an Array," talks about using Array#reverse_each to iterate over an array in reverse order
  • Recipe 4.2, "Rearranging Values Without Using Temporary Variables"
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Sorting an Array
Inhaltsvorschau
You want to sort an array of objects, possibly according to some custom notion of what "sorting" means.
Homogeneous arrays of common data types, like strings or numbers, can be sorted "naturally" by just calling Array#sort:
	[5.01, -5, 0, 5].sort                                # => [-5, 0, 5, 5.01] 

	["Utahraptor", "Ankylosaur", "Maiasaur"].sort

	# => ["Ankylosaur", "Maiasaur", "Utahraptor"]
To sort objects based on one of their data members, or by the results of a method call, use Array#sort_by. This code sorts an array of arrays by size, regardless of their contents:
	arrays = [[1,2,3], [100], [10,20]]  

	arrays.sort_by { |x| x.size }                    # => [[100], [10, 20], [1, 2, 3]]
To do a more general sort, create a code block that compares the relevant aspect of any two given objects. Pass this block into the sort method of the array you want to sort.
This code sorts an array of numbers in ascending numeric order, except that the number 42 will always be at the end of the list:
	[1, 100, 42, 23, 26, 10000].sort do |x, y|

	  x == 42 ? 1 : x <=> y

	end

	# => [1, 23, 26, 100, 10000, 42]
If there is one "canonical" way to sort a particular class of object, then you can have that class implement the <=> comparison operator. This is how Ruby automatically knows how to sort numbers in ascending order and strings in ascending ASCII order: Numeric and String both implement the comparison operator.
The sort_by method sorts an array using a Schwartzian transform (see Recipe 4.6 for an in-depth discussion). This is the most useful customized sort, because it's fast and easy to define. In this example, we use sort_by to sort on any one of an object's fields.
	class Animal

	 attr_reader :name, :eyes, :appendages



	 def initialize(name, eyes, appendages)

	  @name, @eyes, @appendages = name, eyes, appendages

	 end



	 def inspect

	   @name

	 end

	end



	animals = [Animal.new("octopus", 2, 8),

	           Animal.new("spider", 6, 8),

	           Animal.new("bee", 5, 6),

	           Animal.new("elephant", 2, 4),

	           Animal.new("crab", 2, 10)]



	animals.sort_by { |x| x.eyes }

	# => [octopus, elephant, crab, bee, spider]



	animals.sort_by { |x| x.appendages }

	# => [elephant, bee, octopus, spider, crab]
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Ignoring Case When Sorting Strings
Inhaltsvorschau
When you sort a list of strings, the strings beginning with uppercase letters sort before the strings beginning with lowercase letters.
	list = ["Albania", "anteater", "zorilla", "Zaire"]

	list.sort

	# => ["Albania", "Zaire", "anteater", "zorilla"]
You want an alphabetical sort, regardless of case.
Use Array#sort_by. This is both the fastest and the shortest solution.
	list.sort_by { |x| x.downcase }

	# => ["Albania", "anteater", "Zaire", "zorilla"]
The Array#sort_by method was introduced in Recipe 4.5, but it's worth discussing in detail because it's so useful. It uses a technique called a Schwartzian Transform. This common technique is like writing the following Ruby code (but it's a lot faster, because it's implemented in C):
	list.collect { |s| [s.downcase, s] }. 

sort.collect { |subarray| subarray[1] }
It works like this: Ruby creates a new array containing two-element subarrays. Each subarray contains a value of String#downcase, along with the original string. This new array is sorted, and then the original strings (now sorted by their values for String#downcase) are recovered from the subarrays. String#downcase is called only once for each string.
A sort is the most common occurance of this pattern, but it shows up whenever an algorithm calls a particular method on the same objects over and over again. If you're not sorting, you can't use Ruby's internal Schwartzian Transform, but you can save time by caching, or memoizing, the results of each distinct method call.
If you need to implement a Schwartzian Transform in Ruby, it's faster to use a hash than an array:
	m = {}  

	list.sort { |x,y| (m[x] ||= x.downcase) <=> (m[y] ||= y.downcase) }
This technique is especially important if the method you need to call has side effects. You certainly don't want to call such methods more than once!
  • The Ruby FAQ, question 9.15
  • Recipe 4.5, "Sorting an Array"
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Making Sure a Sorted Array Stays Sorted
Inhaltsvorschau
You want to make sure an array stays sorted, even as you replace its elements or add new elements to it.
Subclass Array and override the methods that add items to the array. The new implementations add every new item to a position that maintains the sortedness of the array.
As you can see below, there are a lot of these methods. If you can guarantee that a particular method will never be called, you can get away with not overriding it.
	class 

SortedArray < Array



	  def initialize(*args, &sort_by)

	    @sort_by = sort_by || Proc.new { |x,y| x <=> y }

	    super(*args)

	    sort! &sort_by

	  end



	  def insert(i, v)

	    # The next line could be further optimized to perform a

	    # binary search.

	    insert_before = index(find { |x| @sort_by.call(x, v) == 1 })

	    super(insert_before ? insert_before : -1, v)

	  end



	  def <<(v)

	    insert(0, v)

	  end



	  alias push <<

	  alias unshift <<
Some methods, like collect!, can modify the items in an array, taking them out of sort order. Some methods, like flatten!, can add new elements to strange places in an array. Rather than figuring out a way to implement these methods in a way that preserves the sortedness of the array, we'll just let them run and then re-sort the array.
	  ["collect!", "flatten!", "[]="].each do |method_name|

	    module_eval %{

	      def #{method_name}(*args)

	        super

	        sort! &@sort_by

	      end

	    }

	  end



	  def reverse!

	    #Do nothing; reversing the array would disorder it.

	  end

	end
A SortedArray created from an unsorted array will end up sorted:
	a = SortedArray.new([3,2,1])         # => [1, 2, 3]
Many methods of Array are much faster on sorted arrays, so it's often useful to expend some overhead on keeping an array sorted over time. Removing items from a sorted array won't unsort it, but adding or modifying items can. Keeping a sorted array sorted means intercepting and reimplementing every sneaky way of putting objects into the array.
The SortedArray constructor accepts any code block you can pass into Array#sort, and keeps the array sorted according to that code block. The default code block uses the comparison operator (
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Summing the Items of an Array
Inhaltsvorschau
You want to add together many objects in an array.
There are two good ways to accomplish this in Ruby. Plain vanilla iteration is a simple way to approach the problem:
	collection = [1, 2, 3, 4, 5]

	sum = 0 

	collection.each {|i| sum += i} 

	sum                                       # => 15
However this is such a common action that Ruby has a special iterator method called inject, which saves a little code:
	collection = [1, 2, 3, 4, 5]

	collection. 

inject(0) {|sum, i| sum + i}      # => 15
Notice that in the inject solution, we didn't need to define the variable total variable outside the scope of iteration. Instead, its scope moved into the iteration. In the example above, the initial value for total is the first argument to inject. We changed the += to + because the block given to inject is evaluated on each value of the collection, and the total variable is set to its output every time.
You can think of the inject example as equivalent to the following code:
	collection = [1, 2, 3, 4, 5]

	sum = 0

	sum = sum + 1

	sum = sum + 2

	sum = sum + 3

	sum = sum + 4

	sum = sum + 5
Although inject is the preferred way of summing over a collection, inject is generally a few times slower than each. The speed difference does not grow exponentially, so you don't need to always be worrying about it as you write code. But after the fact, it's a good idea to look for inject calls in crucial spots that you can change to use faster iteration methods like each.
Nothing stops you from using other kinds of operators in your inject code blocks. For example, you could multiply:
	collection = [1, 2, 3, 4, 5]

	collection.inject(1) {|total, i| total * i}  # => 120
Many of the other recipes in this book use inject to build data structures or run calculations on them.
  • Recipe 2.8, "Finding Mean, Median, and Mode"
  • Recipe 4.12, "Building Up a Hash Using Injection"
  • Recipe 5.12, "Building a Histogram"
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Sorting an Array by Frequency of Appearance
Inhaltsvorschau
You want to sort an array so that its least-frequently-appearing items come first.
Build a histogram of the frequencies of the objects in the array, then use it as a lookup table in conjunction with the sort_ by method.
The following method puts the least frequently-appearing objects first. Objects that have the same frequency are sorted normally, with the comparison operator.
	module Enumerable

	  def 

sort_by_frequency

	    histogram = inject(Hash.new(0)) { |hash, x| hash[x] += 1; hash}

	    sort_by { |x| [histogram[x], x] }

	  end

	end



	[1,2,3,4,1,2,4,8,1,4,9,16]. 

sort_by_frequency

	# => [3, 8, 9, 16, 2, 2, 1, 1, 1, 4, 4, 4]
The sort_by_frequency method uses sort_by, a method introduced in Recipe 4.5 and described in detail in Recipe 4.6. The technique here is a little different from other uses of sort_by, because it sorts by two different criteria. We want to first compare the relative frequencies of two items. If the relative frequencies are equal, we want to compare the items themselves. That way, all the instances of a given item will show up together in the sorted list.
The block you pass to Enumerable#sort_by can return only a single sort key for each object, but that sort key can be an array. Ruby compares two arrays by comparing their corresponding elements, one at a time. As soon as an element of one array is different from an element of another, the comparison stops, returning the comparison of the two different elements. If one of the arrays runs out of elements, the longer one sorts first. Here are some quick examples:
	[1,2] <=> [0,2]                        # => 1

	[1,2] <=> [1,2]                        # => 0

	[1,2] <=> [2,2]                        # => -1

	[1,2] <=> [1,1]                        # => 1

	[1,2] <=> [1,3]                        # => -1

	[1,2] <=> [1]                          # => 1

	[1,2] <=> [3]                          # => -1

	[1,2] <=> [0,1,2]                      # => 1

	[1,2] <=> []                           # => 1
In our case, all the arrays contain two elements: the relative frequency of an object in the array, and the object itself. If two objects have different frequencies, the first elements of their arrays will differ, and the items will be sorted based on their frequencies. If two items have the same frequency, the first element of each array will be the same. The comparison method will move on to the second array element, which means the two objects will be sorted based on their values.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Shuffling an Array
Inhaltsvorschau
You want to put the elements of an array in random order.
The simplest way to shuffle an array (in Ruby 1.8 and above) is to sort it randomly:
	[1,2,3].sort_by { rand } # => [1, 3, 2]
This is not the fastest way, though.
It's hard to beat a random sort for brevity of code, but it does a lot of extra work. Like any general sort, a random sort will do about n log n variable swaps. But to shuffle a list, it suffices to put a randomly selected element in each position of the list. This can be done with only n variable swaps.
	class Array

	  def shuffle!  

	    each_index do |i| 

	      j = rand(length-i) + i

	      self[j], self[i] = self[i], self[j]  

	    end

	  end



	  def shuffle  

	    dup.shuffle!  

	  end

	end
If you're shuffling a very large list, either Array#shuffle or Array#shuffle! will be significantly faster than a random sort. Here's a real-world example of shuffling using Array#shuffle:
	class Card

	  def initialize(suit, rank)

	    @suit = suit  

	    @rank = rank  

	  end



	  def to_s

	    "#{@suit} of #{@rank}"

	  end

	end



	class Deck < Array

	  attr_reader :cards  

	  @@suits = %w{Spades Hearts Clubs Diamonds}

	  @@ranks = %w{Ace 2 3 4 5 6 7 8 9 10 Jack Queen King} 



	  def initialize

	    @@suits.each { |suit| @@ranks.each { |rank| self << Card.new(rank, suit) } }

	  end

	end



	deck = Deck.new

	deck.collect { |card| card.to_s }

	# => ["Ace of Spades", "2 of Spades", "3 of Spades", "4 of Spades",…]

	deck.shuffle! 

	deck.collect { |card| card.to_s }

	# => ["6 of Clubs", "8 of Diamonds", "2 of Hearts", "5 of Clubs",…]
  • Recipe 2.5, "Generating Random Numbers"
  • The Facets Core library provides implementations of Array#shuffle and Array#shuffle!
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Getting the N Smallest Items of an Array
Inhaltsvorschau
You want to find the smallest few items in an array, or the largest, or the most extreme according to some other measure.
If you only need to find the single smallest item according to some measure, use Enumerable#min. By default, it uses the <=> method to see whether one item is "smaller" than another, but you can override this by passing in a code block.
	[3, 5, 11, 16].min 

	# => 3

	["three", "five", "eleven", "sixteen"].min

	# => "eleven"

	["three", "five", "eleven", "sixteen"].min { |x,y| x.size <=> y.size }

	# => "five"
Similarly, if you need to find the single largest item, use Enumerable#max.
	[3, 5, 11, 16].max 

	# => 16

	["three", "five", "eleven", "sixteen"].max

	# => "three"

	["three", "five", "eleven", "sixteen"].max { |x,y| x.size <=> y.size }

	# => "sixteen"
By default, arrays are sorted by their natural order: numbers are sorted by value, strings by their position in the ASCII collating sequence (basically alphabetical order, but all lowercase characters precede all uppercase characters). Hence, in the previous examples, "three" is the largest string, and "eleven" the smallest.
It gets more complicated when you need to get a number of the smallest or largest elements according to some measurement: say, the top 5 or the bottom 10. The simplest solution is to sort the list and skim the items you want off of the top or bottom.
	l = [1, 60, 21, 100, -5, 20, 60, 22, 85, 91, 4, 66]

	sorted = l.sort



	#The top 5

	sorted[-5…sorted.size] 

	# => [60, 66, 85, 91, 100]  



	#The bottom 5 

	sorted[0…5] 

	# => [-5, 1, 4, 20, 21]
Despite the simplicity of this technique, it's inefficient to sort the entire list unless the number of items you want to extract approaches the size of the list.
The min and max methods work by picking the first element of the array as a "champion," then iterating over the rest of the list trying to find an element that can beat the current champion on the appropriate metric. When it finds one, that element becomes the new champion. An element that can beat the old champion can also beat any of the other contenders seen up to that point, so one run through the list suffices to find the maximum or minimum.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Building Up a Hash Using Injection
Inhaltsvorschau
You want to create a hash from the values in an array.
As seen in Recipe 4.8, the most straightforward way to solve this kind of problem is to use Enumerable#inject. The inject method takes one parameter (the object to build up, in this case a hash), and a block specifying the action to take on each item. The block takes two parameters: the object being built up (the hash), and one of the items from the array.
Here's a straightforward use of inject to build a hash out of an array of key-value pairs:
	collection = [ [1, 'one'], [2, 'two'], [3, 'three'],

	               [4, 'four'], [5, 'five'] 

	             ]

	

	collection.inject({}) do |hash, value|

	  hash[value.first] = value.last 

	  hash

	end

	# => {5=>"five", 1=>"one", 2=>"two", 3=>"three", 4=>"four"}
Why is there that somewhat incongrous expression hash at the end of the inject block above? Because the next time it calls the block, inject uses the value it got from the block the last time it called the block. When you're using inject to build a data structure, the last line of code in the block should evaluate to the object you're building up: in this case, our hash.
This is probably the most common inject-related gotcha. Here's some code that doesn't work:
	collection.dup.inject({}) { |hash, value| hash[value.first] = value.last }

	# IndexError: index 3 out of string
Why doesn't this work? Because hash assignment returns the assigned value, not the hash.
	Hash.new["key"] = "some value"       # => "some value"
In the broken example above, when inject calls the code block for the second and subsequent times, it does not pass the hash as the code block's first argument. It passes in the last value to be assigned to the hash. In this case, that's a string (maybe "one" or "four"). The hash has been lost forever, and the inject block crashes when it tries to treat a string as a hash.
Hash#update can be used like hash assignment, except it returns the hash instead of the assigned value (and it's slower). So this code will work:
	collection.inject({}) do |hash, value|

	  hash.update value.first => value.last 

	end

	# => {5=>"five", 1=>"ontwo", 2=>"two", 3=>"three", 4=>"four"}
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Extracting Portions of Arrays
Inhaltsvorschau
Given an array, you want to retrieve the elements of the array that occupy certain positions or have certain properties. You might to do this in a way that removes the matching elements from the original array.
To gather a chunk of an array without modifying it, use the array retrieval operator Array#[], or its alias Array#slice.
The array retrieval operator has three forms, which are the same as the corresponding forms for substring accesses. The simplest and most common form is array[index].It takes a number as input, treats it as an index into the array, and returns the element at that index. If the input is negative, it counts from the end of the array. If the array is smaller than the index, it returns nil. If performance is a big consideration for you, Array#at will do the same thing, and it's a little faster than Array#[]:
	a = ("a".."h").to_a                # => ["a", "b", "c", "d", "e", "f", "g", "h"]



	a[0]                               # => "a"

	a[1]                               # => "b"



	a.at(1)                            # => "b" 

	a.slice(1)                         # => "b"

	a[-1]                              # => "h"

	a[-2]                              # => "g"

	a[1000]                            # => nil 

	a[-1000]                           # => nil
The second form is array[range]. This form retrieves every element identified by an index in the given range, and returns those elements as a new array.
A range in which both numbers are negative will retrieve elements counting from the end of the array. You can mix positive and negative indices where that makes sense:
	a[2..5]                                # => ["c", "d", "e", "f"]

	a[2…5]                               # => ["c", "d", "e"]

	a[0..0]                                # => ["a"]

	a[1..-4]                               # => ["b", "c", "d", "e"]

	a[5..1000]                             # => ["f", "g", "h"]



	a[2..0]                                # => []

	a[0…0]                               # => []



	a[-3..2]                               # => []
The third form is
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Computing Set Operations on Arrays
Inhaltsvorschau
You want to find the union, intersection, difference, or Cartesian product of two arrays, or the complement of a single array with respect to some universe.
Array objects have overloaded arithmetic and logical operators to provide the three simplest set operations:
	#Union

	[1,2,3] | [1,4,5]                    # => [1, 2, 3, 4, 5] 



	#Intersection

	[1,2,3] & [1,4,5]                    # => [1]



	#Difference

	[1,2,3] - [1,4,5]                    # => [2, 3]
Set objects overload the same operators, as well as the exclusive-or operator (^).If you already have Arrays, though, it's more efficient to deconstruct the XOR operation into its three component operations.
	require 'set' 

	a = [1,2,3]

	b = [3,4,5]

	a.to_set ^ b.to_set                  # => #<Set: {5, 1, 2, 4}>  

	(a | b) - (a & b)                    # => [1, 2, 4, 5]
Set objects are intended to model mathematical sets: where arrays are ordered and can contain duplicate entries, Sets model an unordered collection of unique items. Set not only overrides operators for set operations, it provides English-language aliases for the three most common operators: Set#union, Set#intersection, and Set#difference. An array can only perform a set operation on another array, but a Set can perform a set operation on any Enumerable.
	array = [1,2,3]

	set = [3,4,5].to_s  

	array & set                      # => TypeError: can't convert Set into Array

	set & array                      # => #<Set: {3}>
You might think that Set objects would be optimized for set operations, but they're actually optimized for constant-time membership checks (internally, a Set is based on a hash). Set union is faster when the left-hand object is a Set object, but intersection and difference are significantly faster when both objects are arrays. It's not worth it to convert arrays into Sets just so you can say you performed set operations on Set objects.
The union and intersection set operations remove duplicate entries from arrays. The difference operation does not remove duplicate entries from an array except as part of a subtraction.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Partitioning or Classifying a Set
Inhaltsvorschau
You want to partition a Set or array based on some attribute of its elements. All elements that go "together" in some code-specific sense should be grouped together in distinct data structures. For instance, if you're partitioning by color, all the green objects in a Set should be grouped together, separate from the group of all the red objects in the Set.
Use Set#divide, passing in a code block that returns the partition of the object it's passed. The result will be a new Set containing a number of partitioned subsets of your original Set.
The code block can accept either a single argument or two arguments. The single-argument version examines each object to see which subset it should go into.
	require 'set' 

	s = Set.new((1..10).collect)

	# => #<Set: {5, 6, 1, 7, 2, 8, 3, 9, 4, 10}>



	# Divide the set into the "true" subset and the "false" subset: that

	# is, the "less than 5" subset and the "not less than 5" subset.

	s.divide { |x| x < 5 }

	# => #<Set: {#<Set: {5, 6, 7, 8, 9, 10}>, #<Set: {1, 2, 3, 4}>}>



	# Divide the set into the "0" subset and the "1" subset: that is, the

	# "even" subset and the "odd" subset.

	s.divide { |x| x % 2 }

	# => #<Set: {#<Set: {6, 2, 8, 4, 10}>, #<Set: {5, 1, 7, 3, 9}>}>



	s = Set.new([1, 2, 3, 'a', 'b', 'c', -1.0, -2.0, -3.0])

	# Divide the set into the "String subset, the "Fixnum" subset, and the

	# "Float" subset.

	s.divide { |x| x.class } 

	# => #<Set: {#<Set: {"a", "b", "c"}>,

	# =>       #<Set: {1, 2, 3}>,

	# =>       #<Set: {-1.0, -3.0, -2.0}>}>
For the two-argument code block version of Set#divide, the code block should return true if both the arguments it has been passed should be put into the same subset.
	s = [1, 2, 3, -1, -2, -4].to_set



	# Divide the set into sets of numbers with the same absolute value.

	s.divide { |x,y| x.abs == y.abs }

	# => #<Set: {#<Set: {-1, 1}>, 

	# =>         #<Set: {2, -2}>, 

	# =>         #<Set: {-4}>,

	# =>         #<Set: {3}>}>



	# Divide the set into sets of adjacent numbers 

	s.divide { |x,y| (x-y).abs == 1 }

	# => #<Set: {#<Set: {1, 2, 3}>,

	# =>         #<Set: {-1}>,

	# =>         #<Set: {-4, -3}>}>
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Chapter 5: Hashes
Inhaltsvorschau
Hashes and arrays are the two basic "aggregate" data types supported by most modern programming lagnguages. The basic interface of a hash is similar to that of an array. The difference is that while an array stores items according to a numeric index, the index of a hash can be any object at all.
Arrays and strings have been built into programming languages for decades, but built-in hashes are a relatively recent development. Now that they're around, it's hard to live without them: they're at least as useful as arrays.
You can create a Hash by calling Hash.new or by using one of the special sytaxes Hash[] or {}. With the Hash[] syntax, you pass in the initial elements as comma-separated object references. With the {} syntax, you pass in the initial contents as comma-separated key-value pairs.
	empty = Hash.new                            # => {}

	empty ={}                                   # => {}

	numbers = { 'two' => 2, 'eight' => 8} # => {"two"=>2, "eight"=>8}

	numbers = Hash['two', 2, 'eight', 8]        # => {"two"=>2, "eight"=>8}
Once the hash is created, you can do hash lookups and element assignments using the same syntax you would use to view and modify array elements:
	numbers["two"]                              # => 2

	numbers["ten"] = 10                         # => 10

	numbers                                     # => {"two"=>2, "eight"=>8, "ten"=>10}
You can get an array containing the keys or values of a hash with Hash#keys or Hash#values. You can get the entire hash as an array with Hash#to_a:
	numbers.keys                                # => ["two", "eight", "ten"]

	numbers.values                              # => [2, 8, 10]

	numbers.to_a                                 # => [["two", 2], ["eight", 8], ["ten", 10]]
Like an array, a hash contains references to objects, not copies of them. Modifications to the original objects will affect all references to them:
	motto = "Don't tread on me"

	flag = { :motto => motto,

	         :picture => "rattlesnake.png"}

	motto.upcase!

	flag[:motto]                               # => "DON'T TREAD ON ME"
The defining feature of an array is its ordering. Each element of an array is assigned a
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Using Symbols as Hash Keys
Inhaltsvorschau
Credit: Ben Giddings
When using a hash, you want the slight optimization you can get by using symbols as keys instead of strings.
Whenever you would otherwise use a quoted string, use a symbol instead. A symbol can be created by either using a colon in front of a word, like :keyname, or by transforming a string to a symbol using String#intern.
	people = Hash.new

	people[:nickname] = 'Matz'

	people[:language] = 'Japanese'

	people['last name'.intern] = 'Matsumoto'

	people[:nickname]                                       # => "Matz"

	people['nickname'.intern]                               # => "Matz"
While 'name' and 'name' appear exactly identical, they're actually different. Each time you create a quoted string in Ruby, you create a unique object. You can see this by looking at the object_id method.
	'name'.object_id                                        # => -605973716

	'name'.object_id                                        # => -605976356

	'name'.object_id                                        # => -605978996
By comparison, each instance of a symbol refers to a single object.
	:name.object_id                                         # => 878862

	:name.object_id                                         # => 878862

	'name'.intern.object_id                                 # => 878862

	'name'.intern.object_id                                 # => 878862
Using symbols instead of strings saves memory and time. It saves memory because there's only one symbol instance, instead of many string instances. If you have many hashes that contain the same keys, the memory savings adds up.
Using symbols as hash keys is faster because the hash value of a symbol is simply its object ID. If you use strings in a hash, Ruby must calculate the hash value of a string each time it's used as a hash key.
  • Recipe 1.7, "Converting Between Strings and Symbols"
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Creating a Hash with a Default Value
Inhaltsvorschau
Credit: Ben Giddings
You're using a hash, and you don't want to get nil as a value when you look up a key that isn't present in the hash. You want to get some more convenient value instead, possibly one calculated dynamically.
A normal hash has a default value of nil:
	h = Hash.new

	h[1]                                           # => nil

	h['do you have this string?']                  # => nil
There are two ways of creating default values for hashes. If you want the default value to be the same object for every hash key, pass that value into the Hash constructor.
	h = Hash.new("nope")

	h[1]                                          # => "nope"

	h['do you have this string?']                 # => "nope"
If you want the default value for a missing key to depend on the key or the current state of the hash, pass a code block into the hash constructor. The block will be called each time someone requests a missing key.
	h = Hash.new { |hash, key| (key.respond_to? :to_str) ? "nope" : nil }

	h[1]                                            # => nil

	h['do you have this string']                    # => "nope"
The first type of custom default value is most useful when you want a default value of zero. For example, this form can be used to calculate the frequency of certain words in a paragraph of text:
	text = 'The rain in Spain falls mainly in the plain.'

	word_count_hash = Hash.new 0                    # => {}

	text.split(/\W+/).each { |word| word_count_hash[word.downcase] += 1 }

	word_count_hash

	# => {"rain"=>1, "plain"=>1, "in"=>2, "mainly"=>1, "falls"=>1,

	#        "the"=>2, "spain"=>1}
What if you wanted to make lists of the words starting with a given character? Your first attempt might look like this:
	first_letter_hash = Hash.new []

	text.split(/\W+/).each { |word| first_letter_hash[word[0,1].downcase] << word }

	first_letter_hash

	                                             # => {}

	first_letter_hash["m"]

	# => ["The", "rain", "in", "Spain", "falls", "mainly", "in", "the", "plain"]
What's going on here? All those words don't start with "m"….
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Adding Elements to a Hash
Inhaltsvorschau
You have some items, loose or in some other data structure, which you want to put into an existing hash.
To add a single key-value pair, assign the value to the element lookup expression for the key: that is, call hash[key]=value. Assignment will override any previous value for that key.
	h = {}

	h["Greensleeves"] = "all my joy"

	h                                   # => {"Greensleeves"=>"all my joy"}

	h["Greensleeves"] = "my delight"

	h                                   # => {"Greensleeves"=>"my delight"}
When you use a string as a hash key, the string is transparently copied and the copy is frozen. This is to avoid confusion should you modify the string in place, then try to use its original form to do a hash lookup:
	key = "Modify me if you can"

	h = { key => 1 }

	key.upcase!                         # => "MODIFY ME IF YOU CAN"

	h[key]                              # => nil

	h["Modify me if you can"]           # => 1



	h.keys                              # => ["Modify me if you can"]

	h.keys[0].upcase!

	# TypeError: can't modify frozen string
To add an array of key-value pairs to a hash, either iterate over the array with Array#each, or pass the hash into Array#inject. Using inject is slower but the code is more concise.
	squares = [[1,1], [2,4], [3,9]]



	results = {}

	squares.each { |k,v| results[k] = v }

	results                             # => {1=>1, 2=>4, 3=>9}



	squares.inject({}) { |h, kv| h[kv[0]] = kv[1]; h }

	# => {1=>1, 2=>4, 3=>9}
To turn a flat array into the key-value pairs of a hash, iterate over the array elements two at a time:
	class Array

	  def into_hash(h)

	    unless size % 2 == 0

	      raise StandardError, "Expected array with even number of elements"

	    end

	    0.step(size-1, 2) { |x| h[self[x]] = self[x+1] }

	    h

	  end

	end



	squares = [1,1,2,3,4,9]

	results = {}

	squares.into_hash(results)            # => {1=>1, 2=>3, 4=>9}



	[1,1,2].into_hash(results)

	# StandardError: Expected array with even number of elements
To insert into a hash every key-value from another hash, use Hash#merge!. If a key is present in both hashes when
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Removing Elements from a Hash
Inhaltsvorschau
Certain elements of your hash have got to go!
Most of the time you want to remove a specific element of a hash. To do that, pass the key into Hash#delete.
	h = {}

	h[1] = 10

	h                                          # => {1=>10}

	h.delete(1)

	h                                          # => {}
Don't try to delete an element from a hash by mapping it to nil. It's true that, by default, you get nil when you look up a key that's not in the hash, but there's a difference between a key that's missing from the hash and a key that's present but mapped to nil. Hash#has_key? will see a key mapped to nil, as will Hash#each and all other methods except for a simple fetch:
	h = {}

	h[5]                                         # => nil

	h[5] = 10

	h[5]                                         # => 10

	h[5] = nil

	h[5]                                         # => nil

	h.keys                                       # => [5]

	h.delete(5)

	h.keys                                       # => []
Hash#delete works well when you need to remove elements on an ad hoc basis, but sometimes you need to go through the whole hash looking for things to remove. Use the Hash#delete_if iterator to delete key-value pairs for which a certain code block returns true (Hash#reject works the same way, but it works on a copy of the Hash). The following code deletes all key-value pairs with a certain value:
	class Hash

	  def delete_value(value)

	    delete_if { |k,v| v == value }

	  end

	end



	h = {'apple' => 'green', 'potato' => 'red', 'sun' => 'yellow',

	     'katydid' => 'green' }

	h.delete_value('green')

	h                                    # => {"sun"=>"yellow", "potato"=>"red"}
This code implements the opposite of Hash#merge; it extracts one hash from another:
	class Hash

	  def remove_hash(other_hash)

	    delete_if { |k,v| other_hash[k] == v }

	  end

	end



	squares = { 1 => 1, 2 => 4, 3 => 9 }

	doubles = { 1 => 2, 2 => 4, 3 => 6 }

	squares.remove_hash(doubles)

	squares                                  # => {1=>1, 3=>9}
Finally, to wipe out the entire contents of a Hash, use Hash#clear:
	h = {}

	1.upto(1000) { |x| h[x] = x }

	h.keys.size                              # => 1000

	h.clear

	h                                        # => {}
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Using an Array or Other Modifiable Object as a Hash Key
Inhaltsvorschau
You want to use a modifiable built-in object (an array or a hash, but not a string) as a key in a hash, even while you modify the object in place. A naive solution tends to lose hash values once the keys are modified:
	coordinates = [10, 5]

	treasure_map = { coordinates => 'jewels' }

	treasure_map[coordinates]                    # => "jewels"



	# Add a z-coordinate to indicate how deep the treasure is buried.

	coordinates << -5



	coordinates                                  # => [10, 5, -5]

	treasure_map[coordinates]                    # => nil

	                                             # Oh no!
The easiest solution is to call the Hash#rehash method every time you modify one of the hash's keys. Hash#rehash will repair the broken treasure map defined above:
	treasure_map.rehash

	treasure_map[coordinates]                    # => "jewels"
If this is too much code, you might consider changing the definition of the object you use as a hash key, so that modifications don't affect the way the hash treats it.
Suppose you want a reliably hashable Array class. If you want this behavior universally, you can reopen the Array class and redefine hash to give you the new behavior. But it's safer to define a subclass of Array that implements a reliable-hashing mixin, and to use that subclass only for the Arrays you want to use as hash keys:
	module ReliablyHashable

	 def hash

	    return object_id

	  end

	end



	class ReliablyHashableArray < Array

	  include ReliablyHashable

	end
It's now possible to keep track of the jewels:
	coordinates = ReliablyHashableArray.new([10,5])

	treasure_map = { coordinates => 'jewels' }

	treasure_map[coordinates]                       # => "jewels"



	# Add a z-coordinate to indicate how deep the treasure is buried.

	coordinates.push(-5)



	treasure_map[coordinates]                       # => "jewels"
Ruby performs hash lookups using not the key object itself but the object's hash code (an integer obtained from the key by calling its hash method). The default implementation of hash, in Object
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Keeping Multiple Values for the Same Hash Key
Inhaltsvorschau
You want to build a hash that might have duplicate values for some keys.
The simplest way is to create a hash that initializes missing values to empty arrays. You can then append items onto the automatically created arrays:
	hash = Hash.new { |hash, key| hash[key] = [] }



	raw_data = [ [1, 'a'], [1, 'b'], [1, 'c'],

	             [2, 'a'], [2, ['b', 'c']],

	             [3, 'c'] ]

	raw_data.each { |x,y| hash[x] << y }

	hash

	# => {1=>["a", "b", "c"], 2=>["a", ["b", "c"]], 3=>["c"]}
A hash maps any given key to only one value, but that value can be an array. This is a common phenomenon when reading data structures from the outside world. For instance, a list of tasks with associated priorities may contain multiple items with the same priority. Simply reading the tasks into a hash keyed on priority would create key collisions, and obliterate all but one task with any given priority.
It's possible to subclass Hash to act like a normal hash until a key collision occurs, and then start keeping an array of values for the key that suffered the collision:
	class MultiValuedHash < Hash

	  def []=(key, value)

	    if has_key?(key)

	      super(key, [value, self[key]].flatten)

	    else

	      super

	    end

	   end

	end



	hash = MultiValuedHash.new

	raw_data.each { |x,y| hash[x] = y }

	hash

	# => {1=>["c", "b", "a"], 2=>["b", "c", "a"], 3=>"c"}
This saves a little bit of memory, but it's harder to write code for this class than for one that always keeps values in an array. There's also no way of knowing whether a value [1,2,3] is a single array value or three numeric values.
  • Recipe 5.2, "Creating a Hash with a Default Value," explains the technique of the dynamic default value in more detail, and explains why you must initalize the empty list within a code block—never within the arguments to Hash.new
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Iterating Over a Hash
Inhaltsvorschau
You want to iterate over a hash's key-value pairs as though it were an array.
Most likely, the iterator you want is Hash#each_pair or Hash#each. These methods yield every key-value pair in the hash:
	hash = { 1 => 'one', [1,2] => 'two', 'three' => 'three' }



	hash.each_pair { |key, value| puts "#{key.inspect} maps to #{value}"}

	# [1, 2] maps to two

	# "three" maps to three

	# 1 maps to one
Note that each and each_pair return the key-value pairs in an apparently random order.
Hash#each_pair and Hash#each let you iterate over a hash as though it were an array full of key-value pairs. Hash#each_pair is more commonly used and slightly more efficient, but Hash#each is more array-like. Hash also provides several other iteration methods that can be more efficient than each.
Use Hash#each_key if you only need the keys of a hash. In this example, a list has been stored as a hash to allow for quick lookups (this is how the Set class works). The values are irrelevant, but each_key can be used to iterate over the keys:
	active_toggles = { 'super' => true, 'meta' => true, 'hyper' => true }

	active_toggles.each_key { |active| puts active }

	# hyper

	# meta

	# super
Use Hash#each_value if you only need the values of a hash. In this example, each_value is used to summarize the results of a survey. Here it's the keys that are irrelevant:
	favorite_colors = { 'Alice' => :red, 'Bob' => :violet, 'Mallory' => :blue,

	                    'Carol' => :blue, 'Dave' => :violet }



	summary = Hash.new 0

	favorite_colors.each_value { |x| summary[x] += 1 }

	summary

	# => {:red=>1, :violet=>2, :blue=>2}
Don't iterate over Hash#each_value looking for a particular value: it's simpler and faster to use has_value? instead.
	hash = {}

	1.upto(10) { |x| hash[x] = x * x }

	hash.has_value? 49                    # => true

	hash.has_value? 81                    # => true

	hash.has_value? 50                    # => false
Removing unprocessed elements from a hash during an iteration prevents those items from being part of the iteration. However, adding elements to a hash during an iteration will not make them part of the iteration.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Iterating Over a Hash in Insertion Order
Inhaltsvorschau
Iterations over a hash happen in a seemingly random order. Sorting the keys or values only works if the keys or values are all mutually comparable. You'd like to iterate over a hash in the order in which the elements were added to the hash.
Use the orderedhash library (see below for how to get it). Its OrderedHash class acts like a hash, but it keeps the elements of the hash in insertion order.
	require ' 

orderedhash'

	h =  

OrderedHash.new

	h[1] = 1

	h["second"] = 2

	h[:third] = 3



	h.keys                                           # => [1, "second", :third]

	h.values                                         # => [1, 2, 3]

	h.each { |k,v| puts "The #{k} counting number is #{v}" }

	# The 1 counting number is 1

	# The second counting number is 2

	# The third counting number is 3
OrderedHash is a subclass of Hash that also keeps an array of the keys in insertion order. When you add a key-value pair to the hash, OrderedHash modifies both the underlying hash and the array. When you ask for a specific hash element, you're using the hash. When you ask for the keys or the values, the data comes from the array, and you get it in insertion order.
Since OrderedHash is a real hash, it supports all the normal hash operations. But any operation that modifies an OrderedHash may also modify the internal array, so it's slower than just using a hash. OrderedHash#delete is especially slow, since it must perform a linear search of the internal array to find the key being deleted. Hash#delete runs in constant time, but OrderedHash#delete takes time proportionate to the size of the hash.
  • You can get OrderedHash from the RAA at http://raa.ruby-lang.org/project/orderedhash/; it's not available as a gem, and it has no setup.rb script, so you'll need to distribute orderedhash.rb with your project, or copy it into your Ruby library path
  • There is a queuehash gem that provides much the same functionality, but it has worse performance than OrderedHash
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Printing a Hash
Inhaltsvorschau
Credit: Ben Giddings
You want to print out the contents of a Hash, but Kernel#puts doesn't give very useful results.
	h = {}

	h[:name] = "Robert"

	h[:nickname] = "Bob"

	h[:age] = 43

	h[:email_addresses] = {:home => "bob@example.com",

	                       :work => "robert@example.com"}

	h

	# => {:email_addresses=>["bob@example.com", "robert@example.com"],

	#         :nickname=>"Bob", :name=>"Robert", :age=>43}

	puts h

	# nicknameBobage43nameRobertemail_addresseshomebob@example.comworkrobert@example.com

	puts h[:email_addresses]

	# homebob@example.comworkrobert@example.com
In other recipes, we sometimes reformat the results or output of Ruby statements so they'll look better on the printed page. In this recipe, you'll see raw, unretouched output, so you can compare different ways of printing hashes.
The easiest way to print a hash is to use Kernel#p. Kernel#p prints out the "inspected" version of its arguments: the string you get by calling inspect on the hash. The "inspected" version of an object often looks like Ruby source code for creating the object, so it's usually readable:
	p h[:email_addresses]

	# {:home=>"bob@example.com", :work=>"robert@example.com"}
For small hashes intended for manual inspection, this may be all you need. However, there are two difficulties. One is that Kernel#p only prints to stdout. The second is that the printed version contains no newlines, making it difficult to read large hashes.
	p h

	# {:nickname=>"Bob", :age=>43, :name=>"Robert", :email_addresses=>{:home=>

	# "bob@example.com", :work=>"robert@example.com"}}
When the hash you're trying to print is too large, the pp ("pretty-print") module produces very readable results:
	require ' 

pp'

	pp h[:email_addresses]

	# {:home=>"bob@example.com", :work=>"robert@example.com"}



	pp h

	# {:email_addresses=>{:home=>"bob@example.com", :work=>"robert@example.com"}

	# :nickname=>"Bob",

	# :name=>"Robert",

	# :age=>43}
There are a number of ways of printing hash contents. The solution you choose depends on the complexity of the hash you're trying to print, where you're trying to print the hash, and your personal preferences. The best general-purpose solution is the
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Inverting a Hash
Inhaltsvorschau
Given a hash, you want to switch the keys and values. That is, you want to create a new hash whose keys are the values of the old hash, and whose values are the keys of the old hash. If the old hash mapped "human" to "wolf;" you want the new hash to map "wolf" to "human."
The simplest technique is to use the Hash#invert method:
	phone_directory = {     'Alice' => '555-1212',

	                        'Bob' => '555-1313',

	                        'Mallory' => '111-1111' }

	phone_directory.invert

	# => {"111-1111"=>"Mallory", "555-1212"=>"Alice", "555-1313"=>"Bob"}
Hash#invert probably won't do what you want if your hash maps more than one key to the same value. Only one of the keys for that value will show up as a value in the inverted hash:
	phone_directory = {     'Alice' => '555-1212',

	                        'Bob' => '555-1313',

	                        'Carol' => '555-1313',

	                        'Mallory' => '111-1111',

	                        'Ted' => '555-1212' }

	phone_directory.invert

	# => {"111-1111"=>"Mallory", "555-1212"=>"Ted", "555-1313"=>"Bob"}
To preserve all the data from the original hash, borrow the idea behind Recipe 5.6, and write a version of invert that keeps an array of values for each key. The following is based on code by Tilo Sloboda:
	class Hash

	  def safe_invert

	    new_hash = {}

	    self.each do |k,v|

	      if v.is_a? Array

	        v.each { |x| new_hash.add_or_append(x, k) }

	      else

	        new_hash.add_or_append(v, k)

	      end

	    end

	    return new_hash

	  end
The add_or_append method a lot like the method MultivaluedHash#[]= defined in Recipe 5.6:
	  def add_or_append(key, value)

	    if has_key?(key)

	      self[key] = [value, self[key]].flatten

	    else

	      self[key] = value

	    end

	  end

	end
Here's safe_invert in action:
	phone_directory.safe_invert

	# => {"111-1111"=>"Mallory", "555-1212"=>["Ted", "Alice"],

	# "555-1313"=>["Bob", "Carol"]}



	phone_directory.safe_invert.safe_invert

	# => {"Alice"=>"555-1212", "Mallory"=>"111-1111", "Ted"=>"555-1212",

	# => "Carol"=>"555-1313", "Bob"=>"555-1313"}
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Choosing Randomly from a Weighted List
Inhaltsvorschau
You want to pick a random element from a collection, where each element in the collection has a different probability of being chosen.
Store the elements in a hash, mapped to their relative probabilities. The following code will work with a hash whose keys are mapped to relative integer probabilities:
	def choose_ 

weighted(weighted)

	  sum = weighted.inject(0) do |sum, item_and_weight|

	    sum += item_and_weight[1]

	  end

	  target = rand(sum)

	  weighted.each do |item, weight|

	    return item if target <= weight

	    target -= weight

	  end

	end
For instance, if all the keys in the hash map to 1, the keys will be chosen with equal probability. If all the keys map to 1, except for one which maps to 10, that key will be picked 10 times more often than any single other key. This algorithm lets you simulate those probability problems that begin like, "You have a box containing 51 black marbles and 17 white marbles…":
	marbles = { :black => 51, :white => 17 }

	3.times { puts choose_weighted(marbles) }

	# black

	# white

	# black
I'll use it to simulate a lottery in which the results have different probabilities of showing up:
	lottery_probabilities = { "You've wasted your money!" => 1000,

	                          "You've won back the cost of your ticket!" => 50,

	                          "You've won two shiny zorkmids!" => 20,

	                          "You've won five zorkmids!" => 10,

	                          "You've won ten zorkmids!" => 5,

	                          "You've won a hundred zorkmids!" => 1 }



	# Let's buy some lottery tickets.

	5.times { puts choose_weighted(lottery_probabilities) }

	# You've wasted your money!

	# You've wasted your money!

	# You've wasted your money!

	# You've wasted your money!

	# You've won five zorkmids!
An extremely naive solution would put the elements in a list and choose one at random. This doesn't solve the problem because it ignores weights altogether: low-weight elements will show up exactly as often as high-weight ones. A less naive solution would be to repeat each element in the list a number of times proportional to its weight. Under this implementation, our simulation of the marble box would contain
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Building a Histogram
Inhaltsvorschau
You have an array that contains a lot of references to relatively few objects. You want to create a histogram, or frequency map: something you can use to see how often a given object shows up in the array.
Build the histogram in a hash, mapping each object found to the number of times it appears.
	module Enumerable

	  def to_histogram

	    inject(Hash.new(0)) { |h, x| h[x] += 1; h}

	  end

	end



	[1, 2, 2, 2, 3, 3].to_histogram

	# => {1=>1, 2=>3, 3=>2}



	["a", "b", nil, "c", "b", nil, "a"].to_histogram

	# => {"a"=>2, "b"=>2, "c"=>1, nil=>2}



	"Aye\nNay\nNay\nAbstaining\nAye\nNay\nNot Present\n".to_histogram

	# => {"Abstaining\n"=>1, "Nay\n"=>3, "Not Present\n"=>1, "Aye\n"=>2}



	survey_results = { "Alice" => :red, "Bob" => :green, "Carol" => :green,

	                   "Mallory" => :blue }

	survey_results.values.to_histogram

	# => {:red=>1, :green=>2, :blue=>1}
Making a histogram is an easy and fast (linear-time) way to summarize a dataset. Histograms expose the relative popularity of the items in a dataset, so they're useful for visualizing optimization problems and dividing the "head" from the "long tail."
Once you have a histogram, you can find the most or least common elements in the list, sort the list by frequency of appearance, or see whether the distribution of items matches your expectations. Many of the other recipes in this book build a histogram as a first step towards a more complex algorithm.
Here's a quick way of visualizing a histogram as an ASCII chart. First, we convert the histogram keys to their string representations so they can be sorted and printed. We also store the histogram value for the key, since we can't do a histogram lookup later based on the string value we'll be using.
	def draw_graph(histogram, char="#")

	  pairs = histogram.keys.collect { |x| [x.to_s, histogram[x]] }.sort
Then we find the key with the longest string representation. We'll pad the rest of the histogram rows to this length, so that the graph bars will line up correctly.
	  largest_key_size = pairs.max { |x,y| x[0].size <=> y[0].size }[0].size
Then we print each key-value pair, padding with spaces as necessary.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Remapping the Keys and Values of a Hash
Inhaltsvorschau
You have two hashes with common keys but differing values. You want to create a new hash that maps the values of one hash to the values of another.
	class Hash

	  def tied_with(hash)

	    remap do |h,key,value|

	      h[hash[key]] = value

	    end.delete_if { |key,value| key.nil? || value.nil? }

	  end
Here is the Hash#remap method:
	  def remap(hash={})

	    each { |k,v| yield hash, k, v }

	    hash

	  end

	end
Here's how to use Hash#tied_with to merge two hashes:
	a = {1 => 2, 3 => 4}

	b = {1 => 'foo', 3 => 'bar'}

	a.tied_with(b)                          # => {"foo"=>2, "bar"=>4}

	b.tied_with(a)                          # => {2=>"foo", 4=>"bar"}
This remap method can be handy when you want to make a similar change to every item in a hash. It is also a good example of using the yield method.
Hash#remap is conceptually similar to Hash#collect, but Hash#collect builds up a nested array of key-value pairs, not a new hash.
  • The Facets library defines methods Hash#update_each and Hash#replace_each! for remapping the keys and values of a hash
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Extracting Portions of Hashes
Inhaltsvorschau
You have a hash that contains a lot of values, but only a few of them are interesting. You want to select the interesting values and ignore the rest.
You can use the Hash#select method to extract part of a hash that follows a certain rule. Suppose you had a hash where the keys were Time objects representing a certain date, and the values were the number of web site clicks for that given day. We'll simulate such as hash with random data:
	require 'time'

	click_counts = {}

	1.upto(30) { |i| click_counts[Time.parse("2006-09-#{i}")] = 400 + rand(700) }

	p click_counts

	# {Sat Sep 23 00:00:00 EDT 2006=>803, Tue Sep 12 00:00:00 EDT 2006=>829,

	# Fri Sep 01 00:00:00 EDT 2006=>995, Mon Sep 25 00:00:00 EDT 2006=>587,

	# …
You might want to know the days when your click counts were low, to see if you could spot a trend. Hash#select can do that for you:
	low_click_days = click_counts.select {|key, value| value < 450 }

	# [[Thu Sep 14 00:00:00 EDT 2006, 449], [Mon Sep 11 00:00:00 EDT 2006, 406],

	#  [Sat Sep 02 00:00:00 EDT 2006, 440], [Mon Sep 04 00:00:00 EDT 2006, 431],

	# …
The array returned by Hash#select contains a number of key-value pairs as two-element arrays. The first element of one of these inner arrays is a key into the hash, and the second element is the corresponding value. This is similar to how Hash#each yields a succession of two-element arrays.
If you want another hash instead of an array of key-value pairs, you can use Hash#inject instead of Hash#select. In the code below, kv is a two-element array containing a key-value pair. kv[0] is a key from click_counts, and kv[1] is the corresponding value.
	low_click_days_hash = click_counts.inject({}) do |h, kv|

	  k, v = kv

	  h[k] = v if v < 450

	  h

	end

	# => {Mon Sep 25 00:00:00 EDT 2006=>403,

	#        Wed Sep 06 00:00:00 EDT 2006=>443,

	#        Thu Sep 28 00:00:00 EDT 2006=>419}
You can also use the Hash.[] constructor to create a hash from the array result of Hash#select:
	low_click_days_hash = Hash[*low_click_days.flatten]

	# => {Thu Sep 14 00:00:00 EDT 2006=>449, Mon Sep 11 00:00:00 EDT 2006=>406,

	#        Sat Sep 02 00:00:00 EDT 2006=>440, Mon Sep 04 00:00:00 EDT 2006=>431,

	#        …
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Searching a Hash with Regular Expressions
Inhaltsvorschau
Credit: Ben Giddings
You want to grep a hash: that is, find all keys and/or values in the hash that match a regular expression.
The fastest way to grep the keys of a hash is to get the keys as an array, and grep that:
	h = { "apple tree" => "plant", "ficus" => "plant",

	      "shrew" => "animal", "plesiosaur" => "animal" }

	h.keys.grep /p/

	# => ["apple tree", "plesiosaur"]
The solution for grepping the values of a hash is similar (substitute Hash#values for Hash#keys), unless you need to map the values back to the keys of the hash. If that's what you need, the fastest way is to use Hash#each to get key-value pairs, and match the regular expression against each value.
	h.inject([]) { |res, kv| res << kv if kv[1] =~ /p/; res }

	# => [["ficus", "plant"], ["apple tree", "plant"]]
The code is similar if you need to find key-value pairs where either the key or the value matches a regular expression:
	class Hash

	  def grep(pattern)

	    inject([]) do |res, kv|

	      res << kv if kv[0] =~ pattern or kv[1] =~ pattern

	      res

	    end

	  end

	end



	h.grep(/pl/)

	# => [["ficus", "plant"], ["apple tree", "plant"], ["plesiosaur", "animal"]]

	h.grep(/plant/)           # => [["ficus", "plant"], ["apple tree", "plant"]]

	h.grep(/i.*u/)            # => [["ficus", "plant"], ["plesiosaur", "animal"]]
Hash defines its own grep method, but it will never give you any results. Hash#grep is inherited from Enumerable#grep, which tries to match the output of each against the given regular expression. Hash#each returns a series of two-item arrays containing key-value pairs, and an array will never match a regular expression. The Hash#grep implementation above is more useful.
Hash#keys.grep and Hash#values.grep are more efficient than matching a regular expression against each key or value in a Hash, but those methods create a new array containing all the keys in the Hash. If memory usage is your primary concern, iterate over each_key or each_value instead:
	res = []

	h.each_key { |k| res << k if k =~ /p/ }

	res                   # => ["apple tree", "plesiosaur"]
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Chapter 6: Files and Directories
Inhaltsvorschau
As programming languages increase in power, we programmers get further and further from the details of the underlying machine language. When it comes to the operating system, though, even the most modern programming languages live on a level of abstraction that looks a lot like the C and Unix libraries that have been around for decades.
We covered this kind of situation in Chapter 3 with Ruby's Time objects, but the issue really shows up when you start to work with files. Ruby provides an elegant object-oriented interface that lets you do basic file access, but the more advanced file libraries tend to look like the C libraries they're based on. To lock a file, change its Unix permissions, or read its metadata, you'll need to remember method names like mtime, and the meaning of obscure constants like File::LOCK_EX and 0644. This chapter will show you how to use the simple interfaces, and how to make the more obscure interfaces easier to use.
Looking at Ruby's support for file and directory operations, you'll see four distinct tiers of support. The most common operations tend to show up on the lowernumbered tiers:
  1. File objects to read and write the contents of files, and Dir objects to list the contents of directories. For examples, see Recipes 6.5, 6.7, and 6.17. Also see Recipe 6.13 for a Ruby-idiomatic approach.
  2. Class methods of File to manipulate files without opening them. For instance, to delete a file, examine its metadata, or change its permissions. For examples, see Recipes 6.1, 6.3, and 6.4.
  3. Standard libraries, such as find to walk directory trees, and fileutils to perform common filesystem operations like copying files and creating directories. For examples, see Recipes 6.8, 6.12, and 6.20.
  4. Gems like file-tail, lockfile, and rubyzip, which fill in the gaps left by the standard library. Most of the file-related gems covered in this book deal with specific file formats, and are covered in Chapter 12.
Kernel#open is the simplest way to open a file. It returns a Filel object that you can read from or write to, depending on the "mode" constant you pass in. I'll introduce read mode and write mode here; there are several others, but I'll talk about most of those as they come up in recipes.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Checking to See If a File Exists
Inhaltsvorschau
Given a filename, you want to see whether the corresponding file exists and is the right kind for your purposes.
Most of the time you'll use the File.file? predicate, which returns true only if the file is an existing regular file (that is, not a directory, a socket, or some other special file).
	filename = 'a_file.txt'

	File.file? filename                           # => false



	require 'fileutils'

	FileUtils.touch(filename)

	File.file? filename                           # => true
Use the File.exists? predicate instead if the file might legitimately be a directory or other special file, or if you plan to create a file by that name if it doesn't exist. File.exists? will return true if a file of the given name exists, no matter what kind of file it is.
	directory_name = 'a_directory'

	FileUtils.mkdir(directory_name)

	File.file? directory_name            # => false 

File.exists? directory_name          # => true
A true response from File.exists? means that the file is present on the filesystem, but says nothing about what type of file it is. If you open up a directory thinking it's a regular file, you're in for an unpleasant surprise. This is why File.file? is usually more useful than File.exists?.
Ruby provides several other predicates for checking the type of a file: the other commonly useful one is File.directory?:
	File.directory? directory_name          # => true

	File.directory? filename                # => false
The rest of the predicates are designed to work on Unix systems. File.blockdev? tests or block-device files (such as hard-drive partitions), File.chardev? tests for character-device files (such as TTYs), File.socket? tests for socket files, and File.pipe? tests for named pipes,
	File.blockdev? '/dev/hda1'                 # => true

	File.chardev? '/dev/tty1'                  # => true

	File.socket? '/var/run/mysqld/mysqld.sock' # => true

	system('mkfifo named_pipe')

	File.pipe? 'named_pipe'                    # => true
File.symlink? tests whether a file is a symbolic link to another file, but you only need to use it when you want to treat symlinks differently from other files. A symlink to a regular file will satisfy
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Checking Your Access to a File
Inhaltsvorschau
You want to see what you can do with a file: whether you have read, write, or (on Unix systems) execute permission on it.
Use the class methods File.readable?, File.writeable?, and File.executable?.
 

File.readable?('/bin/ls')      # => true

	 

File.readable?('/etc/passwd-') # => false



	filename = 'test_file'

	File.open(filename, 'w') {}



	File.writable?(filename) # => true

	File.writable?('/bin/ls') # => false



	 

File.executable?('/bin/ls') # => true

	 

File.executable?(filename) # => false
Ruby's file permission tests are Unix-centric, but readable? and writable? work on any platform; the rest fail gracefully when the OS doesn't support them. For instance, Windows doesn't have the Unix notion of execute permission, so File.executable? always returns true on Windows.
The return value of a Unix permission test depends in part on whether your user owns the file in question, or whether you belong to the Unix group that owns it. Ruby provides convenience tests File.owned? and File.grpowned? to check this.
	File.owned? 'test_file'       # => true

	File.grpowned? 'test_file'    # => true

	File.owned? '/bin/ls'         # => false
On Windows, File.owned? always returns true (even for a file that belongs to another user) and File.grpowned? always returns false.
The File methods described above should be enough to answer most permission questions about a file, but you can also see a file's Unix permissions in their native form by looking at the file's mode. The mode is a number, each bit of which has a different meaning within the Unix permission system. You can view a file's mode with File::Lstat#mode.
The result of mode contains some extra bits describing things like the type of a file. You probably want to strip that information out by masking those bits. This example demonstrates that the file originally created in the solution has a Unix permission mask of 0644:
	File.lstat('test_file').mode & 0777           # Keep only the permission bits.

	# => 420                                       # That is, 0644 octal.
readable?, writable
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Changing the Permissions on a File
Inhaltsvorschau
You want to control access to a file by modifying its Unix permissions. For instance, you want to make it so that everyone on your system can read a file, but only you can write to it.
Unless you've got a lot of Unix experience, it's hard to remember the numeric codes for the nine Unix permission bits. Probably the first thing you should do is define constants for them. Here's one constant for every one of the permission bits. If these names are too concise for you, you can name them USER_READ, GROUP_WRITE, OTHER_ EXECUTE, and so on.
	class File

	  U_R = 0400

	  U_W = 0200

	  U_X = 0100

	  G_R = 0040

	  G_W = 0020

	  G_X = 0010

	  O_R = 0004

	  O_W = 0002

	  O_X = 0001

	end
You might also want to define these three special constants, which you can use to set the user, group, and world permissions all at once:
	class File

	  A_R = 0444

	  A_W = 0222

	  A_X = 0111

	  end
Now you're ready to actually change a file's permissions. Every Unix file has a permission bitmap, or mode, which you can change (assuming you have the permissions!) by calling File.chmod. You can manipulate the constants defined above to get a new mode, then pass it in along with the filename to File.chmod.
The following three chmod calls are equivalent: for the file my_file, they give readwrite access to to the user who owns the file, and restrict everyone else to read-only access. This is equivalent to the permission bitmap 11001001, the octal number 0644, or the decimal number 420.
open("my_file", "w") {}



File.chmod(File::U_R | File::U_W | File::G_R | File::O_R, "my_file")

File.chmod(File::A_R | File::U_W, "my_file")

File.chmod(0644, "my_file")                     # Bitmap: 110001001



File::U_R | File::U_W | File::G_R | File::O_R   # => 420

File::A_R | File::U_W                           # => 420

0644 # => 420

File.lstat("my_file").mode & 0777               # => 420
Note how I build a full permission bitmap by combining the permission constants with the OR operator (|).
A Unix file has nine associated permission bits that are consulted whenever anyone tries to access the file. They're divided into three sets of three bits. There's one set for the user who owns the file, one set is for the user group who owns the file, and one set is for everyone else.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Seeing When a File Was Last Used Problem
Inhaltsvorschau
You want to see when a file was last accessed or modified.
The result of File.stat contains a treasure trove of metadata about a file. Perhaps the most useful of its methods are the two time methods mtime (the last time anyone wrote to the file), and atime (the last time anyone read from the file).
	open("output", "w") { |f| f << "Here's some output.\n" }

	stat = 

File.stat("output")

	stat.mtime                               # => Thu Mar 23 12:23:54 EST 2006

	stat.atime                               # => Thu Mar 23 12:23:54 EST 2006

	

	sleep(2)

	open("output", "a") { |f| f << "Here's some more output.\n" }

	stat = File.stat("output")

	stat.mtime                               # => Thu Mar 23 12:23:56 EST 2006

	stat.atime                               # => Thu Mar 23 12:23:54 EST 2006

	

	sleep(2)

	open("output") { |f| contents = f.read }

	stat = File.stat("output")

	stat.mtime                               # => Thu Mar 23 12:23:56 EST 2006

	stat.atime                               # => Thu Mar 23 12:23:58 EST 2006
A file's atime changes whenever data is read from the file, and its mtime changes whenever data is written to the file.
There's also a ctime method, but it's not as useful as the other two. Contrary to semi-popular belief, ctime does not track the creation time of the file (there's no way to track this in Unix). A file's ctime is basically a more inclusive version of its mtime. The ctime changes not only when someone modifies the contents of a file, but when someone changes its permissions or its other metadata.
All three methods are useful for separating the files that actually get used from the ones that just sit there on disk. They can also be used in sanity checks.
Here's code for the part of a game that saves and loads the game state to a file. As a deterrent against cheating, when the game loads a save file it performs a simple check against the file's modification time. If it differs from the timestamp recorded inside the file, the game refuses to load the save file.
The save_game method is responsible for recording the timestamp:
	def save_game(file)

	  score = 1000

	  open(file, "w") do |f|

	    f.puts(score)

	    f.puts(Time.new.to_i)

	  end

	end
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Listing a Directory
Inhaltsvorschau
You want to list or process the files or subdirectories within a directory.
If you're starting from a directory name, you can use Dir.entries to get an array of the items in the directory, or Dir.foreach to iterate over the items. Here's an exampleof each run on a sample directory:
	# See the chapter intro to get the create_tree library

	require 'create_tree'

	create_tree 'mydir' =>

	  [ {'subdirectory' => [['file_in_subdirectory', 'Just a simple file.']] },

	  '.hidden_file', 'ruby_script.rb', 'text_file' ] 

Dir.entries('mydir')

	

	# => [".", "..", ".hidden_file", "ruby_script.rb", "subdirectory",

	# "text_file"]

	

	 

Dir.foreach('mydir') { |x| puts x if x != "." && x != ".."}

	# .hidden_file

	# ruby_script.rb

	# subdirectory

	# text_file
You can also use Dir[] to pick up all files matching a certain pattern, using a format similar to the bash shell's glob format (and somewhat less similar to the wildcard format used by the Windows command-line shell):
	# Find all the "regular" files and subdirectories in mydir. This excludes

	# hidden files, and the special directories . and ..

	Dir["mydir/*"]

	# => ["mydir/ruby_script.rb", "mydir/subdirectory", "mydir/text_file"]

	

	# Find all the .rb files in mydir

	Dir["mydir/*.rb"]                 # =>  ["mydir/ruby_script.rb"]
You can also open a directory handle with Dir#open, and treat it like any other Enumerable. Methods like each,each_with_index, grep, and reject will all work (but see below if you want to call them more than once). As with File#open, you should do your directory processing in a code block so that the directory handle will get closed once you're done with it.
	Dir.open('mydir') { |d| d.grep /file/ }

	# => [".hidden_file", "text_file"]

	

	Dir.open('mydir') { |d| d.each { |x| puts x } }

	# .

	# ..

	# .hidden_file

	# ruby_script.rb

	# subdirectory

	# text_file
Reading entries from a Dir object is more like reading data from a file than iterating over an array. If you call one of the Dir instance methods and then want to call another one on the same Dir object, you'll need to call
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Reading the Contents of a File
Inhaltsvorschau
You want to read some or all of a file into memory.
Open the file with Kernel#open, and pass in a code block that does the actual reading. To read the entire file into a single string, use IO#read:
	#Put some stuff into a file.

	open('sample_file', 'w') do |f|

	  f.write("This is line one.\nThis is line two.")

	end

	

	# Then read it back out.

	open('sample_file') { |f| f.read }

	# => "This is line one.\nThis is line two."
To read the file as an array of lines, use IO#readlines:
	open('sample_file') { |f| f.readlines }

	# => ["This is line one.\n", "This is line two."]
To iterate over each line in the file, use IO#each. This technique loads only one line into memory at a time:
	open('sample_file').each { |x| p x }

	# "This is line one.\n"

	# "This is line two."
How much of the file do you want to read into memory at once? Reading the entire file in one gulp uses memory equal to the size of the file, but you end up with a string, and you can use any of Ruby's string processing techniques on it.
The alternative is to process the file one chunk at a time. This uses only the memory needed to store one chunk, but it can be more difficult to work with, because any given chunk may be incomplete. To process a chunk, you may end up reading the next chunk, and the next. This code reads the first 50-byte chunk from a file, but it turns out not to be enough:
	puts open('conclusion') { |f| f.read(50) }

	# "I know who killed Mr. Lambert," said Joe. "It was
If a certain string always marks the end of a chunk, you can pass that string into IO#each to get one chunk at a time, as a series of strings. This lets you process each full chunk as a string, and it uses less memory than reading the entire file.
If a certain string always marks the end of a chunk, you can pass that string into IO#each to get one chunk at a time, as a series of strings. This lets you process each full chunk as a string, and it uses less memory than reading the entire file.
	# Create a file…

	open('end_separated_records', 'w') do |f|

	  f << %{This is record one.

	It spans multiple lines.ENDThis is record two.END}

	end

	

	# And read it back in.

	open('end_separated_records') { |f| f.each('END') { |record| p record } }

	# "This is record one.\nIt spans multiple lines.END"

	# "This is record two.END"
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Writing to a File
Inhaltsvorschau
You want to write some text or Ruby data structures to a file. The file might or might not exist. If it does exist, you might want to overwrite the old contents, or just append new data to the end of the file.
Open the file in write mode ('w'). The file will be created if it doesn't exist, and truncated to zero bytes if it does exist. You can then use IO#write or the << operator to write strings to the file, as though the file itself were a string and you were appending to it.
You can also use IO#puts or IO#p to write lines to the file, the same way you can use Kernel#puts or Kernel#p to write lines to standard output.
Both of the following chunks of code destroy the previous contents of the file output, then write a new string to the file:
	open('output', 'w') { |f| f << "This file contains great truths.\n" }

	open('output', 'w') do |f|

	  f.puts 'The great truths have been overwritten with an advertisement.'

	end

	

	open('output') { |f| f.read }

	# => "The great truths have been overwritten with an advertisement.\n"
To append to a file without overwriting its old contents, open the file in append mode ('a') instead of write mode:
	open('output', "a") { |f| f.puts 'Buy Ruby(TM) brand soy sauce!' }

	

	open('output') { |f| puts f.read }

	# The great truths have been overwritten with an advertisement.

	# Buy Ruby(TM) brand soy sauce!
Sometimes you'll only need to write a single (possibly very large) string to a file. Usually, though, you'll be getting your strings one at a time from a data structure or some other source, and you'll call puts or the append operator within some kind of loop:
	open('output', 'w') do |f|

	  [1,2,3].each { |i| f << i << ' and a ' }

	end

	open('output') { |f| f.read }     # => "1 and a 2 and a 3 and a "
Since the << operator returns the filehandle it wrote to, you can chain calls to it. As seen above, this feature lets you write multiple strings to a file in a single line of Ruby code.
Because opening a file in write mode destroys the file's existing contents, you should only use it when you don't care about the old contents, or after you've read them into memory for later use. Append mode is nondestructive, making it useful for files like log iles, which need to be updated periodically without destroying their old contents.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Writing to a Temporary File
Inhaltsvorschau
You want to write data to a secure temporary file with a unique name.
Create a Tempfile object. It has all the methods of a File object, and it will be in a location on disk guaranteed to be unique.
	require 'tempfile'

	out = Tempfile.new("tempfile")

	out.path # =>              "/tmp/tempfile23786.0"
A Tempfile object is opened for read-write access (mode w+), so you can write to it and then read from it without having to close and reopen it:
	out << "Some text."

	out.rewind

	out.read # => "Some text."

	out.close
Note that you can't pass a code block into the Tempfile constructor: you have to assign the temp file to an object, and call Tempfile#close when you're done.
To avoid security problems, use the Tempfile class to generate temp file names, instead of writing the code yourself. The Tempfile class creates a file on disk guaranteed not to be in use by any other thread or process, and sets that file's permissions so that only you can read or write to it. This eliminates any possibility that a hostile process might inject fake data into the temp file, or read what you write.
The name of a temporary file incorporates the string you pass into the Tempfile constructor, the process ID of the current process ($$, or $PID if you've done an include English), and a unique number. By default, temporary files are created in Dir:: tmpdir (usually /tmp), but you can pass in a different directory name:
	out = Tempfile.new("myhome_tempfile", "/home/leonardr/temp/")
No matter where you create your temporary files, when your process exits, all of its temporary files are automatically destroyed. If you want the data you wrote to temporary files to live longer than your process, you should copy or move the temporary files to "real" files:
	require 'fileutils'

	FileUtils.mv(out.path, "/home/leonardr/old_tempfile")
The tempfile assumes that the operating system can atomically open a file and get an exclusive lock on it. This doesn't work on all filesystems. Ara Howard's lockfile library (available as a gem of the same name) uses linking, which is atomic everywhere.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Picking a Random Line from a File
Inhaltsvorschau
You want to choose a random line from a file, without loading the entire file into memory.
Iterate over the file, giving each line a chance to be the randomly selected one:
	module Enumerable

	  def random_line

	    selected = nil

	    each_with_index { |line, lineno| selected = line if rand < 1.0/lineno }

	    return selected.chomp if selected

	  end

	end

	

	#Create a file with 1000 lines

	open('random_line_test', 'w') do |f|

	  1000.times { |i| f.puts "Line #{i}" }

	end

	

	#Pick 

random lines from the file.

	f = open('random_line_test')

	f.random_line # => "Line 520"

	f.random_line # => nil

	f.rewind

	f.random_line # => "Line 727"
The obvious solution reads the entire file into memory;
	File.open('random_line_test') do |f|

	l = f.readlines

	l[rand(l.size)].chomp

	end

	# => "Line 708"
The recommended solution is just as fast, and only reads one line at a time into memory. However, once it's done, the file pointer has been set to the end of the file and you can't access the file anymore without calling File#rewind. If you want to pick a lot of random lines from a file, reading the entire file into memory might be preferable to iterating over it multiple times.
This recipe makes for a good command-line tool. The following code uses the special variable $., which holds the number of the line most recently read from a file:
	$ ruby -e 'rand < 1.0/$. and line = $_ while gets; puts line.chomp if line'
The algorithm works because, although lines that come earlier in the file have a better chance of being selected initially, they also have more chances to be replaced by a later line. A proof by induction demonstrates that the algorithm gives equal weight to each line in the file.
The base case is a file of a single line, where it will obviously work: any value of Kernel#rand will be less than 1, so the first line will always be chosen.
Now for the inductive step. Assume that the algorithm works for a file of n lines: that is, each of the first n lines has a 1/n chance of being chosen. Then, add another line to the file and process the new line. The chance that line n+1 will become the randomly chosen line is
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Comparing Two Files
Inhaltsvorschau
You want to see if two files contain the same data. If they differ, you might want to represent the differences between them as a string: a patch from one to the other.
If two files differ, it's likely that their sizes also differ, so you can often solve the problem quickly by comparing sizes. If both files are regular files with the same size, you'll need to look at their contents.
This code does the cheap checks first:
  1. If one file exists and the other does not, they're not the same.
  2. If neither file exists, say they're the same.
  3. If the files are the same file, they're the same.
  4. If the files are of different types or sizes, they're not the same.
	class File

	  def File.same_contents(p1, p2)

	    return false if File.exists?(p1) != File.exists?(p2)

	    return true if !File.exists?(p1)

	    return true if File.expand_path(p1) == File.expand_path(p2)

	    return false if File.ftype(p1) != File.ftype(p2) ||

	       File.size(p1) != File.size(p2)
Otherwise, it compares the files contents, a block at a time:
	    open(p1) do |f1|

	      open(p2) do |f2|

	        blocksize = f1.lstat.blksize

	        same = true

	        while same && !f1.eof? && !f2.eof?

	          same = f1.read(blocksize) == f2.read(blocksize)

	        end

	        return same

	      end

	    end

	  end

	end
To illustrate, I'll create two identical files and compare them. I'll then make them slightly different, and compare them again.
	1.upto(2) do |i|

	  open("output#{i}", 'w') { |f| f << 'x' * 10000 }

	end

	File.same_contents('output1', 'output2')           # => true

	open("output1", 'a') { |f| f << 'x' }

	open("output2", 'a') { |f| f << 'y' }

	File.same_contents('output1', 'output2')           # => false

	

	File.same_contents('nosuchfile', 'output1')        # => false

	File.same_contents('nosuchfile1', 'nosuchfile2')   # => true
The code in the Solution works well if you only need to determine whether two files are identical. If you need to see the differences between two files, the most useful tool is is Austin Ziegler's Diff::LCS library, available as the diff-lcs
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Performing Random Access on "Read-Once" Input Streams
Inhaltsvorschau
You have an IO object, probably a socket, that doesn't support random-access methods like seek, pos=, and rewind. You want to treat this object like a file on disk, where you can jump around and reread parts of the file.
The simplest solution is to read the entire contents of the socket (or as much as you're going to need) and put it into a StringIO object. You can then treat the StringIO object exactly like a file:
	require 'socket'

	require 'stringio'

	

	sock = TCPSocket.open("www.example.com", 80)

	sock.write("GET /\n")

	

	file = StringIO.new(sock.read)

	file.read(10)                                # => "<HTML>\r\n<H"

	file.rewind

	file.read(10)                                # => "<HTML>\r\n<H"

	file.pos = 90

	file.read(15)                                # => " this web page "
A socket is supposed to work just like a file, but sometimes the illusion breaks down. Since the data is coming from another computer over which you have no control, you can't just go back and reread data you've already read. That data has already been sent over the pipe, and the server doesn't care if you lost it or need to process it again.
If you have enough memory to read the entire contents of a socket, it's easy to put the results into a form that more closely simulates a file on disk. But you might not want to read the entire socket, or the socket may be one that keeps sending data until you close it. In that case you'll need to buffer the data as you read it. Instead of using memory for the entire contents of the socket (which may be infinite), you'll only use memory for the data you've actually read.
This code defines a BufferedIO class that adds data to an internal StringIO as it's read from its source:
	class 

BufferedIO

	  def initialize(io)

	    @buff = StringIO.new

	    @source = io

	    @pos = 0

	  end



	  def read(x=nil)

	    to_read = x ? to_read = x+@buff.pos-@buff.size : nil

	    _append(@source.read(to_read)) if !to_read or to_read > 0

	    @buff.read(x)

	  end



	  def pos=(x)

	   read(x-@buff.pos) if x > @buff.size

	    @buff.pos = x

	  end

	

	  def seek(x, whence=IO::SEEK_SET)

	    case whence

	      when IO::SEEK_SET then self.pos=(x)

	      when IO::SEEK_CUR then self.pos=(@buff.pos+x)

	      when IO::SEEK_END then read; self.pos=(@buff.size-x)

	      # Note: SEEK END reads all the socket data.

	    end

	    pos

	  end



	  # Some methods can simply be delegated to the buffer.

	  ["pos", "rewind", "tell"].each do |m|

	  module_eval "def #{m}\n@buff.#{m}\nend"

	  end



	  private



	    def _append(s)

	  @buff << s

	    @buff.pos -= s.size

	  end

	end
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Walking a Directory Tree
Inhaltsvorschau
You want to recursively process every subdirectory and file within a certain directory.
Suppose that the directory tree you want to walk looks like this (see this chapter's introduction section for the create_tree library that can build this directory tree automatically):
	require 'create_tree'

	create_tree './' =>

	  [ 'file1',

	    'file2',

	         { 'subdir1/' => [ 'file1' ] },

	         { 'subdir2/' => [ 'file1',

	                      'file2',

	                       { 'subsubdir/' => [ 'file1' ] }

	                     ]

	    }

	   ]
The simplest solution is to load all the files and directories into memory with a big recursive file glob, and iterate over the resulting array. This uses a lot of memory because all the filenames are loaded into memory at once:
	Dir['**/**']

	# => ["file1", "file2", "subdir1", "subdir2", "subdir1/file1",

	#     "subdir2/file1", "subdir2/file2", "subdir2/subsubdir",

	#     "subdir2/subsubdir/file1"]
A more elegant solution is to use the find method in the Find module. It performs a depth-first traversal of a directory tree, and calls the given code block on each directory and file. The code block should take as an argument the full path to a directory or file.
This snippet calls Find.find with a code block that simply prints out each path it receives. This demonstrates how Ruby performs the traversal:
	require 'find' 

Find.find('./') { |path| puts path }

	# ./

	# ./subdir2

	# ./subdir2/subsubdir

	# ./subdir2/subsubdir/file1

	# ./subdir2/file2

	# ./subdir2/file1

	# ./subdir1

	# ./subdir1/file1

	# ./file2

	# ./file1
Even if you're not a system administrator, the demands of keeping your own files organized will frequently call for you to process every file in a directory tree. You may want to backup, modify, or delete each file in the directory structure, or you may just want to see what's there.
Normally you'll want to at least look at every file in the tree, but sometimes you'll want to skip certain directories. For instance, you might know that a certain directory is full of a lot of large files you don't want to process. When your block is passed a path to a directory, you can prevent
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Locking a File
Inhaltsvorschau
You want to prevent other threads or processes from modifying a file that you're working on.
Open the file, then lock it with File#flock. There are two kinds of lock; pass in the File constant for the kind you want.
  • File::LOCK_EX gives you an exclusive lock, or write lock. If your thread has an exclusive lock on a file, no other thread or process can get a lock on that file. Use this when you want to write to a file without anyone else being able to write to it.
  • File::LOCK_SH will give you a shared lock, or read lock. Other threads and processes can get their own shared locks on the file, but no one can get an exclusive lock. Use this when you want to read a file and know that it won't change while you're reading it.
Once you're done using the file, you need to unlock it. Call File#flock again, and pass in File::LOCK_UN as the lock type. You can skip this step if you're running on Windows.
The best way to handle all this is to enclose the locking and unlocking in a method that takes a block, the way open does:
	  def flock(file, mode)

	    success = file.flock(mode)

	    if success

	      begin

	        yield file

	      ensure

	        file.flock(File::LOCK_UN)

	    end

	  end

	  return success

	end
This makes it possible to lock a file without having to worry about unlocking it later. Even if your block raises an exception, the file will be unlocked and another thread can use it.
	open('output', 'w') do |f|

	  flock(f, File::LOCK_EX) do |f|

	  f << "Kiss me, I've got a write lock on a file!"

	  end

	end
Different operating systems support different ways of locking files. Ruby's flock implementation tries to hide the differences behind a common interface that looks like Unix's file locking interface. In general, you can use flock as though you were on Unix, and your scripts will work across platforms.
On Unix, both exclusive and shared locks work only if all threads and processes play by the rules. If one thread has an exclusive lock on a file, another thread can still open the file without locking it and wreak havoc by overwriting its contents. That's why it's important to get a lock on any file that might conceivably be used by another thread or another process on the system.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Backing Up to Versioned Filenames
Inhaltsvorschau
You want to copy a file to a numbered backup before overwriting the original file. More generally: rather than overwriting an existing file, you want to use a new file whose name is based on the original filename.
Use String#succ to generate versioned suffixes for a filename until you find one that doesn't already exist:
	class File

	  def File.versioned_filename(base, first_suffix='.0')

	    suffix = nil

	    filename = base

	    while File.exists?(filename)

	      suffix = (suffix ? suffix.succ : first_suffix)

	      filename = base + suffix

	    end

	    return filename

	  end

	end

	

	5.times do |i|

	  name = File.versioned_filename('filename.txt')

	  open(name, 'w') { |f| f << "Contents for run #{i}" }

	  puts "Created #{name}"

	end

	# Created filename.txt

	# Created filename.txt.0

	# Created filename.txt.1

	# Created filename.txt.2

	# Created filename.txt.3
If you want to copy or move the original file to the versioned filename as a prelude to writing to the original file, include the ftools library to add the class methods File. copy and File.move. Then call versioned_filename and use File.copy or File.move to put the old file in its new place:
	require 'ftools'

	class File

	def File.to_backup(filename, move=false)

	   new_filename = nil

	   if File.exists? filename

	     new_filename = File. 

versioned_filename(filename)

	     File.send(move ? :move : :copy, filename, new_filename)

	   end

 	   return new_filename

	 end

	end
Let's back up filename.txt a couple of times. Recall from earlier that the files filename.txt.[0-3] already exist.
	    File.to_backup('filename.txt')                  # => "filename.txt.4"

	    File.to_backup('filename.txt')                  # => "filename.txt.5"
Now let's do a destructive backup:
	File.to_backup('filename.txt', true)                # => "filename.txt.6"

	File.exists? 'filename.txt'                         # => false
You can't back up what doesn't exist:
	File.to_backup('filename.txt')                      # => nil
If you anticipate more than 10 versions of a file, you should add additional zeroes to the initial suffix. Otherwise,
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Pretending a String Is a File
Inhaltsvorschau
You want to call code that expects to read from an open file object, but your source is a string in memory. Alternatively, you want to call code that writes its output to a file, but have it actually write to a string.
The StringIO class wraps a string in the interface of the IO class. You can treat it like a file, then get everything that's been "written" to it by calling its string method.
Here's a StringIO used as an input source:
	require 'stringio'

	s = StringIO.new %{I am the very model of a modern major general.

	I've information vegetable, animal, and mineral.}

	

	s.pos                                 # => 0

	s.each_line { |x| puts x }

	# I am the very model of a modern major general.

	# I've information vegetable, animal, and mineral.

	s.eof?                                # => true

	s.pos                                 # => 95

	s.rewind

	s.pos                                 # => 0

	s.grep /general/

	# => ["I am the very model of a modern major general.\n"]
Here are StringIO objects used as output sinks:
	s = StringIO.new

	s.write('Treat it like a file.')

	s.rewind

	s.write("Act like it's")

	s.string							 # => "Act like it's a file."

	

	require 'yaml'

	s = StringIO.new

	YAML.dump(['A list of', 3, :items], s)

	puts s.string

	# ---

	# - A list of

	# - 3

	# - :items
The Adapter is a common design pattern: to make an object acceptable as input to a method, it's wrapped in another object that presents the appropriate interface. The StringIO class is an Adapter between String and File (or IO), designed for use with methods that work on File or IO instances. With a StringIO, you can disguise a string as a file and use those methods without them ever knowing they haven't really been given a file.
For instance, if you want to write unit tests for a library that reads from a file, the simplest way is to pass in predefined StringIO objects that simulate files with various contents. If you need to modify the output of a method that writes to a file, a StringIO can capture the output, making it easy to modify and send on to its final destination.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Redirecting Standard Input or Output
Inhaltsvorschau
You don't want the standard input, output, or error of your process to go to the default IO objects set up by the Ruby interpreter. You want them to go to other filetype objects of your own choosing.
You can assign any IO object (a File, a Socket, or what have you) to the global variables $stdin, $stdout, or $stderr. You can then read from or write to those objects as though they were the originals.
This short Ruby program demonstrates how to redirect the Kernel methods that print to standard output. To avoid confusion, I'm presenting it as a standalone Ruby program rather than an interactive irb session.
	#!/usr/bin/ruby -w

	# ./redirect_stdout.rb

	require 'stringio'

	new_stdout = StringIO.new



	$stdout = new_stdout

	puts "Hello, hello."

	puts "I'm writing to standard 

output."



	$stderr.puts "#{new_stdout.size} bytes written to standard ouput so far."

	$stderr.puts "You haven't seen anything on the screen yet, but you soon will:"

	$stderr.puts new_stdout.string
Run this program and you'll see the following:
	$ ruby redirect_stdout.rb

	46 bytes written to standard output so far.

	You haven't seen anything on the screen yet, but you soon will:

	Hello, hello.

	I'm writing to standard output.
If you have any Unix experience, you know that when you run a Ruby script from the command line, you can make the shell redirect its standard input, output, and error streams to files or other programs. This technique lets you do the same thing from within a Ruby script.
You can use this as a quick and dirty way to write errors to a file, write output to a StringIO object (as seen above), or even read input from a socket. Within a script, you can programatically decide where to send your output, or receive standard input from multiple sources. These things are generally not possible from the command line without a lot of fancy shell scripting.
The redirection technique is especially useful when you've written or inherited a script that prints text to standard output, and you need to make it capable of printing to any file-like object. Rather than changing almost every line of your code, you can just set
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Processing a Binary File
Inhaltsvorschau
You want to read binary data from a file, or write it to one.
Since Ruby strings make no distinction between binary and text data, processing a binary file needn't be any different than processing a text file. Just make sure you add "b" to your file mode when you open a binary file on Windows.
This code writes 10 bytes of binary data to a file, then reads it back:
	open('binary', 'wb') do |f|

	  (0..100).step(10) { |b| f << b.chr }

	end

	

	s = open('binary', 'rb') { |f| f.read }

	# => "\000\n\024\036(2<FPZd"
If you want to process a binary file one byte at a time, you'll probably enjoy the way each_byte returns each byte of the file as a number, rather than as single-character strings:
	open('binary', 'rb') { |f| f.each_byte { |b| puts b } }

	# 0

	# 10

	# 20

	# …

	# 90

	# 100
The methods introduced earlier to deal with text files work just as well for binary files, assuming that your binary files are supposed to be processed from beginning to end, the way text files typically are. If you want random access to the contents of a binary file, you can manipulate your file object's "cursor."
Think of the cursor as a pointer to the first unread byte in the open file. The current position of the cursor is accessed by the method IO#pos. When you open the file, it's set to zero, just before the first byte. You can then use IO#read to read a number of bytes starting from the current position of the cursor, incrementing the cursor as a side effect.
	f = open('binary')

	f.pos                                     # => 0

	f.read(1)                                 # => "\000"

	f.pos                                     # => 1
You can also just set pos to jump to a specific byte in the file:
	f.pos = 4                                 # => 4

	f.read(2)                                 # => "(2"

	f.pos                                     # => 6
You can use IO#seek to move the cursor forward or backward relative to its current position (with File::SEEK_CUR), or to move to a certain distance from the end of a file (with File::SEEK_END). Unlike the iterator methods, which go through the entire file once, you can use
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Deleting a File
Inhaltsvorschau
You want to delete a single file, or a whole directory tree.
Removing a file is simple, with File.delete:
	import 'fileutils'

	FileUtils.touch "doomed_file"

	File.exists? "doomed_file"                    # => true

	File.delete "doomed_file"

	File.exists? "doomed_file"                    # => false
Removing a directory tree is also fairly simple. The most confusing thing about it is the number of different methods Ruby provides to do it. The method you want is probably FileUtils.remove_dir, which recursively deletes the contents of a directory:
	Dir.mkdir "doomed_directory"

	File.exists? "doomed_directory"            # => true 

FileUtils.remove_dir "doomed_directory"

	File.exists? "doomed_directory"            # => false
Ruby provides several methods for removing directories, but you really only need remove_dir. Dir.delete and FileUtils.rmdir will only work if the directory is already empty. The rm_r and rm_rf defined in FileUtils are similar to remove_dir, but if you're a Unix user you may find their names more mneumonic.
You should also know about the :secure option to rm_rf, because the remove_dir method and all its variants are vulnerable to a race condition when you remove a world-writable directory. The risk is that a process owned by another user might create a symlink in that directory while you're deleting it. This would make you delete the symlinked file along with the files you actually meant to delete.
Passing in the :secure option to rm_rf slows down deletions significantly (it has to change the permissions on the directory before deleting it), but it avoids the race condition. If you're running Ruby 1.8, you'll also need to hack the FileUtils module a little bit to work around a bug (the bug is fixed in Ruby 1.9):?
	# A hack to make a 

method used by rm_rf actually available

	module FileUtils

	  module_function :fu_world_writable?

	end

	

	Dir.mkdir "/tmp/doomed_directory"

	FileUtils.rm_rf("/tmp/doomed_directory", :secure=>true)

	File.exists? "/tmp/doomed_directory"            # => false
Why isn't the :secure option the default for rm_rf? Because secure deletion isn't thread-safe: it actually changes the current working directory of the process. You need to choose between thread safety and a possible security hole.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Truncating a File
Inhaltsvorschau
You want to truncate a file to a certain length, probably zero bytes.
Usually, you want to destroy the old contents of a file and start over. Opening a file for write access will automatically truncate it to zero bytes, and let you write new contents to the file:
	filename = 'truncate.txt'

	open(filename, 'w') { |f| f << "All of this will be truncated." }

	File.size(filename)                  # => 30

	

	f = open(filename, 'w') {}

	File.size(filename)                  # => 0
If you just need to truncate the file to zero byt es, and not write any new contents to it, you can open it with an access mode of File::TRUNC.
	open(filename, 'w') { |f| f << "Here are some new contents." }

	

	File.size(filename)                        # => 27

	

	f = open(filename, File::TRUNC) {}

	File.size(filename)                        # => 0
You can't actually do anything with a FILE whose access mode is File::TRUNC:
	open(filename, File::TRUNC) do |f|

	  f << "At last, an empty file to write to!"

	end

	# IOError: not opened for writing
Transient files are the most likely candidates for truncation. Log files are often truncated, automatically or by hand, before they grow too large.
The most common type of truncation is truncating a file to zero bytes, but the File.truncate method can truncate a file to any number of bytes, not just zero. You can also use the instance method, File#truncate, to truncate a file you've opened for writing:
	f = open(filename, 'w') do |f|

	  f << 'These words will remain intact after the file is truncated.'

	end

	File.size(filename) # => 59

	

	File.truncate(filename, 30)

	File.size(filename)              # => 30

	open(filename) { |f| f.read }    # => "These words will remain intact"
These methods don't always make a file smaller. If the file starts out smaller than the size you give, they append zero-bytes (\000) to the end of file until the file reaches the specified size.
	f = open(filename, "w") { |f| f << "Brevity is the soul of wit." }

	File.size(filename)                 # => 27

	File.truncate(filename, 30)

	File.size(filename)                 # => 30

	open(filename) { |f| f.read }

	# => "Brevity is the soul of wit.\000\000\000"
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Finding the Files You Want
Inhaltsvorschau
You want to locate all the files in a directory hierarchy that match some criteria. For instance, you might want to find all the empty files, all the MP3 files, or all the files named "README."
Use the Find.find method to walk the directory structure and accumulate a list of matching files.
Pass in a block to the following method and it'll walk a directory tree, testing each file against the code block you provide. It returns an array of all files for which the value of the block is true.
	require 'find'

	module Find

	  def match(*paths)

	    matched = []

	    find(*paths) { |path| matched << path if yield path }

	    return matched

	  end

	  module_function :match

	end
Here's what Find.match might return if you used it on a typical disorganized home directory:
	Find.match("./") { |p| File.lstat(p).size == 0 }

	# => ["./Music/cancelled_download.MP3", "./tmp/empty2", "./tmp/empty1"]



	Find.match("./") { |p| ext = p[-4…p.size]; ext && ext.downcase == ".mp3" }

	# => ["./Music/The Snails - Red Rocket.mp3",

	# => "./Music/The Snails - Moonfall.mp3", "./Music/cancelled_download.MP3"]



	Find.match("./") { |p| File.split(p)[1] == "README" }

	# => ["./rubyprog-0.1/README", "./tmp/README"]
This is an especially useful chunk of code for system administration tasks. It gives you functionality at least as powerful as the Unix find command, but you can write your search criteria in Ruby and you won't have to remember the arcane syntax of find.
As with Find.walk itself, you can stop Find.match from processing a directory by calling Find.prune:
	Find.match("./") do |p|

	  Find.prune if p == "./tmp"

	  File.split(p)[1] == "README"

	end

	# => ["./rubyprog-0.1/README"]
You can even look inside each file to see whether you want it:
	# Find all files that start with a particular phrase.

	must_start_with = "This Ruby program"

	Find.match("./") do |p|

	  if File.file? p

	    open(p) { |f| f.read(must_start_with.size) == must_start_with }

	  else

	    false

	  end

	end

	# => ["./rubyprog-0.1/README"]
A few other useful things to search for using this function:
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Finding and Changing the Current Working Directory
Inhaltsvorschau
You want to see which directory the Ruby process considers its current working directory, or change that directory.
To find the current working directory, use Dir.getwd:
 

Dir.getwd                     # => "/home/leonardr"
To change the current working directory, use Dir.chdir:
 

Dir.chdir("/bin")

	Dir.getwd          # => "/bin"

	File.exists? "ls"  # => true
The current working directory of a Ruby process starts out as the directory you were in when you started the Ruby interpreter. When you refer to a file without providing an absolute pathname, Ruby assumes you want a file by that name in the current working directory. Ruby also checks the current working directory when you require a library that can't be found anywhere else.
The current working directory is a useful default. If you're writing a Ruby script that operates on a directory tree, you might start from the current working directory if the user doesn't specify one.
However, you shouldn't rely on the current working directory being set to any particular value: this makes scripts brittle, and prone to break when run from a different directory. If your Ruby script comes bundled with libraries, or needs to load additional files from subdirectories of the script directory, you should set the working directory in code.
You can change the working directory as often as necessary, but it's more reliable to use absolute pathnames, even though this can make your code less portable. This is especially true if you're writing multithreaded code.
The current working directory is global to a process. If multiple threads are running code that changes the working directory to different values, you'll never know for sure what the working directory is at any given moment.
  • Recipe 6.18, "Deleting a File," shows some problems created by a process-global working directory
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Chapter 7: Code Blocks and Iteration
Inhaltsvorschau
In Ruby, a code block (or just "block") is an object that contains some Ruby code, and the context neccesary to execute it. Code blocks are the most visually distinctive aspect of Ruby, and also one of the most confusing to newcomers from other languages. Essentially, a Ruby code block is a method that has no name.
Most other languages have something like a Ruby code block: C's function pointers, C++'s function objects, Python's lambdas and list comprehensions, Perl's anonymous functions, Java's anonymous inner classes. These features live mostly in the corners of those languages, shunned by novice programmers. Ruby can't be written without code blocks. Of the major languages, only Lisp is more block-oriented.
Unlike most other languages, Ruby makes code blocks easy to create and imposes few restrictions on them. In every other chapter of this book, you'll see blocks passed into methods like it's no big deal (which it isn't):
	[1,2,3].each { |i| puts i}

	# 1

	# 2

	# 3
In this chapter, we'll show you how to write that kind of method, the kinds of method that are useful to write that way, and when and how to treat blocks as first class objects.
Ruby provides two syntaxes for creating code blocks. When the entire block will fit on one line, it's most readable when enclosed in curly braces:
	[1,2,3].each { |i| puts i }

	# 1

	# 2

	# 3
When the block is longer than one line, it's more readable to begin it with the do keyword and end it with the end keyword:
	[1,2,3].each 

do |i|

	  if i % 2 == 0

	    puts "#{i} is even."

	  else

	    puts "#{i} is odd."

	  end

	end

	# 1 is odd.

	# 2 is even.

	# 3 is odd.
Some people use the bracket syntax when they're interested in the return value of the block, and the do…end syntax when they're interested in the block's side effects.
Keep in mind that the bracket syntax has a higher precedence than the do..end syntax. Consider the following two snippets of code:
	1.upto 3 do |x|

	  puts x

	end

	# 1

	# 2

	# 3



	1.upto 3 { |x| puts x }

	# SyntaxError: compile error
In the second example, the code block binds to the number 3, not to the function call
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Creating and Invoking a Block
Inhaltsvorschau
You want to put some Ruby code into an object so you can pass it around and call it later.
By this time, you should familiar with a block as some Ruby code enclosed in curly brackets. You might think it possible to define a block object as follows:
	aBlock = { |x| puts x }                  # WRONG



	# SyntaxError: compile error
That doesn't work because a block is only valid Ruby syntax when it's an argument to a method call. There are several equivalent methods that take a block and return it as an object. The most favored method is Kernel# lambda:
	aBlock = lambda { |x| puts x }           # RIGHT
To call the block, use the call method:
	aBlock.call "Hello World!"

	# Hello World!
The ability to assign a bit of Ruby code to a variable is very powerful. It lets you write general frameworks and plug in specific pieces of code at the crucial points.
As you'll find out in Recipe 7.2, you can accept a block as an argument to a method by prepending & to the argument name. This way, you can write your own trivial version of the lambda method:
	def my_lambda(&aBlock)

	  aBlock

	end



	b = my_lambda { puts "Hello World My Way!" }

	b.call

	# Hello World My Way!
A newly defined block is actually a Proc object.
	b.class                                  # => Proc
You can also initialize blocks with the Proc constructor or the method Kernel#proc. The methods Kernel#lambda, Kernel#proc, and Proc.new all do basically the same thing. These three lines of code are nearly equivalent:
	aBlock = Proc.new { |x| puts x }

	aBlock = proc { |x| puts x }

	aBlock = lambda { |x| puts x }
What's the difference? Kernel#lambda is the preferred way of creating block objects, because it gives you block objects that act more like Ruby methods. Consider what happens when you call a block with the wrong number of arguments:
	add_lambda = lambda { |x,y| x + y }



	add_lambda.call(4)

	# ArgumentError: wrong number of arguments (1 for 2)



	add_lambda.call(4,5,6)

	# ArgumentError: wrong number of arguments (3 for 2)
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Writing a Method That Accepts a Block
Inhaltsvorschau
You want to write a method that can accept and call an attached code block: a method that works like Array#each, Fixnum#upto, and other built-in Ruby methods.
You don't need to do anything special to make your method capable of accepting a block. Any method can use a block if the caller passes one in. At any time in your method, you can call the block with yield:
	def call_twice

	  puts "I'm about to call your block." 

yield

	  puts "I'm about to call your block again."

	  yield

	end



	call_twice { puts "Hi, I'm a talking  

code block." }

	# I'm about to call your block.

	# Hi, I'm a talking code block.

	# I'm about to call your block again.

	# Hi, I'm a talking code block.
Another example:
	def repeat(n)

	 if block_given?

	   n.times { yield }

	  else

	    raise ArgumentError.new("I can't repeat a block you don't give me!")

	  end

	end



	repeat(4) { puts "Hello." }

	# Hello.

	# Hello.

	# Hello.

	# Hello.



	repeat(4)

	# ArgumentError: I can't repeat a block you don't give me!
Since Ruby focuses so heavily on iterator methods and other methods that accept code blocks, it's important to know how to use code blocks in your own methods.
You don't have to do anything special to make your method capable of taking a code block. A caller can pass a code block into any Ruby method; it's just that there's no point in doing that if the method never invokes yield.
	puts("Print this message.") { puts "And also run this code block!" }

	# Print this message.
The yield keyword acts like a special method, a stand-in for whatever code block was passed in. When you call it, it's exactly as the code block were a Proc object and you had invoked its call method.
This may seem mysterious if you're unfamiliar with the practice of passing blocks around, but it is usually the preferred method of calling blocks in Ruby. If you feel more comfortable receiving a code block as a "real" argument to your method, see Recipe 7.3.
You can pass in arguments to yield (they'll be passed to the block) and you can do things with the value of the yield statement (this is the value of the last statement in the block).
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Binding a Block Argument to a Variable
Inhaltsvorschau
You've written a method that takes a code block, but it's not enough for you to simply call the block with yield. You need to somehow bind the code block to a variable, so you can manipulate the block directly. Most likely, you need to pass it as the code block to another method.
Put the name of the block variable at the end of the list of your method's arguments. Prefix it with an ampersand so that Ruby knows it's a block argument, not a regular argument.
An incoming code block will be converted into a Proc object and bound to the block variable. You can pass it around to other methods, call it directly using call, or yield to it as though you'd never bound it to a variable at all. All three of the following methods do exactly the same thing:
	def repeat(n)

	  n.times { yield } if block_given?

	end

	repeat(2) { puts "Hello." }

	# Hello.

	# Hello.

	def repeat(n, &block)

	  n.times { block.call } if block

	end

	repeat(2) { puts "Hello." }

	# Hello.

	# Hello.



	def repeat(n, &block)

	  n.times { yield } if block

	end

	repeat(2) { puts "Hello." }

	# Hello.

	# Hello.
If &foo is the name of a method's last argument, it means that the method accepts an optional block named foo. If the caller chooses to pass in a block, it will be made available as a Proc object bound to the variable foo. Since it is an optional argument, foo will be nil if no block is actually passed in. This frees you from having to call Kernel#block_given? to see whether or not you got a block.
When you call a method, you can pass in any Proc object as the code block by prefixing the appropriate variable name with an ampersand. You can even do this on a Proc object that was originally passed in as a code block to your method.
Many methods for collections, like each, select, and detect, accept code blocks. It's easy to wrap such methods when your own methods can bind a block to a variable. Here, a method called biggest finds the largest element of a collection that gives a true result for the given block:
	def biggest(collection, &block)

	  block ? collection.select(&block).max : collection.max

	end



	array = [1, 2, 3, 4, 5]

	biggest(array) {|i| i < 3}                  # => 2

	biggest(array) {|i| i != 5 }                   # => 4

	biggest(array)                                 # => 5
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Blocks as Closures: Using Outside Variables Within a Code Block
Inhaltsvorschau
You want to share variables between a method, and a code block defined within it.
Just reference the variables, and Ruby will do the right thing. Here's a method that adds a certain number to every element of an array:
	def add_to_all(array, number)

	  array.collect { |x| x + number }

	end



	add_to_all([1, 2, 3], 10)              # => [11, 12, 13]
Enumerable#collect can't access number directly, but it's passed a block that can access it, since number was in scope when the block was defined.
A Ruby block is a closure: it carries around the context in which it was defined. This is useful because it lets you define a block as though it were part of your normal code, then tear it off and send it to a predefined piece of code for processing.
A Ruby block contains references to the variable bindings, not copies of the values. If the variable changes later, the block will have access to the new value:
	tax_percent = 6

	position = lambda do

	  "I have always supported a #{tax_percent}% tax on imported limes."

	end

	position.call

	# => "I have always supported a 6% tax on imported limes."



	tax_percent = 7.25

	position.call

	# => "I have always supported a 7.25% tax on imported limes."
This works both ways: you can rebind or modify a variable from within a block.
	counter = 0

	4.times { counter += 1; puts "Counter now #{counter}"}

	# Counter now 1

	# Counter now 2

	# Counter now 3

	# Counter now 4

	counter                                                # => 4
This is especially useful when you want to simulate inject or collect in conjunction with a strange iterator. You can create a storage object outside the block, and add things to it from within the block. This code simulates Enumerable#collect, but it collects the elements of an array in reverse order:
	accumulator = []

	[1, 2, 3].reverse_each { |x| accumulator << x + 1 }



	accumulator                  # => [4, 3, 2]
The accumulator variable is not within the scope of Array#reverse_each, but it is within the scope of the block.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Writing an Iterator Over a Data Structure
Inhaltsvorschau
You've created a custom data structure, and you want to implement an each method for it, or you want to implement an unusual way of iterating over an existing data structure.
Complex data structures are usually constructed out of the basic data structures: hashes, arrays, and so on. All of the basic data structures have defined the each method. If your data structure is composed entirely of scalar values and these simple data structures, you can write a new each method in terms of the each methods of its components.
Here's a simple tree data structure. A tree contains a single value, and a list of children (each of which is a smaller tree).
	class Tree

	  attr_reader :value

	  def initialize(value)

	    @value = value

	    @children = []

	  end



	  def <<(value)

	    subtree = Tree.new(value)

	    @children << subtree

	    return subtree

	  end

	end
Here's code to create a specific Tree (Figure 7-1):
	t = Tree.new("Parent")

	child1 = t << "Child 1"

	child1 << "Grandchild 1.1"

	child1 << "Grandchild 1.2"

	child2 = t << "Child 2"

	child2 << "Grandchild 2.1"
Figure 7-1: A simple tree
How can we iterate over this data structure? Since a tree is defined recursively, it makes sense to iterate over it recursively. This implementation of Tree#each yields the value stored in the tree, then iterates over its children (the children are stored in an array, which already supports each) and recursively calls Tree#each on every child tree.
	class Tree

	  def each

	    yield value

	    @children.each do |child_node|

	      child_node.each { |e| yield e }

	    end

	  end

	end
The each method traverses the tree in a way that looks right:
	t.each { |x| puts x }

	# Parent

	# Child 1

	# Grandchild 1.1

	# Grandchild 1.2

	# Child 2

	# Grandchild 2.1
The simplest way to build an iterator is recursively: to use smaller iterators until you've covered every element in your data structure. But what if those iterators aren't there? More likely, what if they're there but they give you elements in the wrong order? You'll need to go down a level and write some loops.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Changing the Way an Object Iterates
Inhaltsvorschau
You want to use a data structure as an Enumerable, but the object's implementation of #each doesn't iterate the way you want. Since all of Enumerable's methods are based on each, this makes them all useless to you.
Here's a concrete example: a simple array.
	array = %w{bob loves alice}

	array.collect { |x| x.capitalize }

	# => ["Bob", "Loves", "Alice"]
Suppose we want to call collect on this array, but we don't want collect to use each: we want it to use reverse_each. Something like this hypothetical collect_reverse method:
	array.collect_reverse { |x| x.capitalize }

	# => ["Alice", "Loves", "Bob"]
Actually defining a collect_reverse method would add significant new code and only solve part of the problem. We could overwrite the array's each implementation with a singleton method that calls reverse_each, but that's hacky and it would surely have undesired side effects.
Fortunately, there's an elegant solution with no side effects: wrap the object in an Enumerator. This gives you a new object that acts like the old object would if you'd swapped out its each method:
	require 'enumerator'

	reversed_array = array.to_enum(:reverse_each)

	reversed_array.collect { |x| x.capitalize }

	# => ["Alice", "Loves", "Bob"]



	reversed_array.each_with_index do |x, i|

	  puts %{#{i}=>"#{x}"}

	end

	# 0=>"alice"

	# 1=>"loves"

	# 2=>"bob"
Note that you can't use the Enumerator for our array as though it were the actual array. Only the methods of Enumerable are supported:
	reversed_array[0]

	# NoMethodError: undefined method '[]' for #<Enumerable::Enumerator:0xb7c2cc8c>
Whenever you're tempted to reimplement one of the methods of Enumerable, try using an Enumerator instead. It's like modifying an object's each method, but it doesn't affect the original object.
This can save you a lot of work. Suppose you have a tree data structure that provides three different iteration styles: each_prefix, each_postfix, and each_infix. Rather than implementing the methods of Enumerable for all three iteration styles, you can let each_prefix be the default implementation of each, and call tree.to_enum(:each_postfix
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Writing Block Methods That Classify or Collect
Inhaltsvorschau
The basic block methods that come with the Ruby standard library aren't enough for you. You want to define your own method that classifies the elements in an enumeration (like Enumerable#detect and Enumerable#find_all), or that does a transformation on each element in an enumeration (like Enumerable#collect).
You can usually use inject to write a method that searches or classifies an enumeration of objects. With inject you can write your own versions of methods such as detect and find_all:
	module Enumerable

	  def find_no_more_than(limit)

	    inject([]) do |a,e|

	      a << e if yield e

	      return a if a.size >= limit

	      a

	    end

	  end

	end
This code finds at most three of the even numbers in a list:
	a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

	a.find_no_more_than(3) { |x| x % 2 == 0 }         # => [2, 4, 6]
If you find yourself needing to write a method like collect, it's probably because, for your purposes, collect itself yields elements in the wrong order. You can't use inject, because that yields elements in the same order as collect.
You need to find or write an iterator that yields elements in the order you want. Once you've done that, you have two options: you can write a collect equivalent on top of the iterator method, or you can use the iterator method to build an Enumerable object, and call its collect method (as seen in Recipe 7.6).
We discussed these block methods in more detail in Chapter 4, because arrays are the simplest and most common Enumerable data type, and the most common. But almost any data structure can be enumerated, and a more complex data structure can be enumerated in more different ways.
As you'll see in Recipe 9.4, the Enumerable methods, like detect and inject, are actually implemented in terms of each. The detect and inject methods yield to the code block every element that comes out of each. The value of the yield statement is used to determine whether the element matches some criteria.
In a method like detect, the iteration may stop once it finds an element that matches. In a method like find_all, the iteration goes through all elements, collecting the ones that match.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Stopping an Iteration
Inhaltsvorschau
You want to interrupt an iteration from within the code block you passed into it.
The simplest way to interrupt execution is to use break. A break statement will jump out of the closest enclosing loop defined in the current method:
	1.upto(10) do |x|

	  puts x

	  break if x == 3

	end

	# 1

	# 2

	# 3
The break statement is simple but it has several limitations. You can't use break within a code block defined with Proc.new or (in Ruby 1.9 and up) Kernel#proc. If this is a problem for you, use lambda instead:
	aBlock = Proc.new do |x|

	  puts x

	  break if x == 3

	  puts x + 2

	end



	aBlock.call(5)

	# 5

	# 7



	aBlock.call(3)

	# 3

	# LocalJumpError: break from proc-closure
More seriously, you can't use break to jump out of multiple loops at once. Once a loop has run, there's no way to know whether it completed normally or by using break.
The simplest way around this problem is to enclose the code you want to skip within a catch block with a descriptive symbolic name. You can then throw the corresponding symbol when you want to jump to the end of the catch block. This lets you skip out of any number of nested loops and method calls.
The throw/catch syntax isn't exception handling—exceptions use a raise/rescue syntax. This is a special flow control construct designed to replace the use of exceptions for flow control (as sometimes happens in Java programs). It's a bit like an old style global GOTO, capable of suddenly moving execution to a faraway part of your program. It keeps your code more readable than a GOTO, though, because it's restricted: a throw can only jump to the end of a corresponding catch block.
The best example of the catch..throw syntax is the Find.find function described in Recipe 6.12. When you pass a code block into Find.find, it yields up every directory and file in a certain directory tree. When your code block is given a directory, it can stop find from recursing into that directory by calling Find.prune, which throws a :prune symbol. Using break would stop the find operation altogether; throwing a symbol lets Find.prune
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Looping Through Multiple Iterables in Parallel
Inhaltsvorschau
You want to traverse multiple iteration methods simultaneously, probably to match up the corresponding elements in several different arrays.
The SyncEnumerator class, defined in the generator library, makes it easy to iterate over a bunch of arrays or other Enumerable objects in parallel. Its each method yields a series of arrays, each array containing one item from each underlying Enumerable object:
	require 'generator'



	enumerator = SyncEnumerator.new(%w{Four seven}, %w{score years},

	                                %w{and ago})

	enumerator.each do |row|

	  row.each { |word| puts word }

	  puts '---'

	end

	# Four

	# score

	# and

	# ---

	# seven

	# years

	# ago

	# ---



	enumerator = SyncEnumerator.new(%w{Four and}, %w{score seven years ago})

	enumerator.each do |row|

	  row.each { |word| puts word }

	  puts '---'

	end

	# Four

	# score

	# ---

	# and

	# seven

	# ---

	# nil

	# years

	# ---

	# nil

	# ago

	# ---
You can reproduce the workings of a SyncEnumerator by wrapping each of your Enumerable objects in a Generator object. This code acts like SyncEnumerator#each, only it yields each individual item instead of arrays containing one item from each Enumerable:
	def interosculate(*enumerables) 

generators = enumerables.collect { |x|  

Generator.new(x) }

	  done = false

	  until done

	    done = true

	    generators.each do |g|

	      if g.next?

	        yield g.next

	        done = false

	      end

	    end

	  end

	end



	interosculate(%w{Four and}, %w{score seven years ago}) do |x|

	  puts x

	end

	# Four

	# score

	# and

	# seven

	# years

	# ago
Any object that implements the each method can be wrapped in a Generator object. If you've used Java, think of a Generator as being like a Java Iterator object. It keeps track of where you are in a particular iteration over a data structure.
Normally, when you pass a block into an iterator method like each, that block gets called for every element in the iterator without interruption. No code outside the block will run until the iterator is done iterating. You can stop the iteration by writing a
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Hiding Setup and Cleanup in a Block Method
Inhaltsvorschau
You have a setup method that always needs to run before custom code, or a cleanup method that needs to run afterwards. You don't trust the person writing the code (possibly yourself) to remember to call the setup and cleanup methods.
Create a method that runs the setup code, yields to a code block (which contains the custom code), then runs the cleanup code. To make sure the cleanup code always runs, even if the custom code throws an exception, use a begin/finally block.
	def between_setup_and_cleanup

	  setup

	  begin

	   yield

	  finally

	    cleanup

	  end

	end
Here's a concrete example. It adds a DOCTYPE and an HTML tag to the beginning of an HTML document. At the end, it closes the HTML tag it opened earlier. This saves you a little bit of work when you're generating HTML files.
	def write_html(out, doctype=nil)

	  doctype ||= %{<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"

	           "http://www.w3.org/TR/html4/loose.dtd">}

	  out.puts doctype

	  out.puts '<html>'

	  begin

	    yield out

	  ensure

	    out.puts '</html>'

	  end

	end



	write_html($stdout) do |out|

	  out.puts '<h1>Sorry, the Web is closed.</h1>'

	end

	# <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"

	#      "http://www.w3.org/TR/html4/loose.dtd">

	# <html>

	# <h1>Sorry, the Web is closed.</h1>

	# </html>
This useful technique shows up most often when there are scarce resources (such as file handles or database connections) that must be closed when you're done with them, lest they all get used up. A language that makes the programmer remember these resources tends to leak those resources, because programmers are lazy. Ruby makes it easy to be lazy and still do the right thing.
You've probably used this technique already, with the the Kernel#open and File#open methods for opening files on disk. These methods accept a code block that manipulates an already open file. They open the file, call your code block, and close the file once you're done:
	open('output.txt', 'w') do |out|

	  out.puts 'Sorry, the filesystem is also closed.'

	end
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Coupling Systems Loosely with Callbacks
Inhaltsvorschau
You want to combine different types of objects without hardcoding them full of references to each other.
Use a callback system, in which objects register code blocks with each other to be executed as needed. An object can call out to its registered callbacks when it needs something, or it can send notification to the callbacks when it does something.
To implement a callback system, write a "register" or "subscribe" method that accepts a code block. Store the registered code blocks as Proc objects in a data structure: probably an array (if you only have one type of callback) or a hash (if you have multiple types). When you need to call the callbacks, iterate over the data structure and call each of the registered code blocks.
Here's a mixin module that gives each instance of a class its own hash of "listener" callback blocks. An outside object can listen for a particular event by calling subscribe with the name of the event and a code block. The dispatcher itself is responsible for calling notify with an appropriate event name at the appropriate time, and the outside object is responsible for passing in the name of the event it wants to "listen" for.
	module EventDispatcher

	  def setup_ 

listeners

	    @event_dispatcher_listeners = {}

	  end



	  def subscribe(event, &callback)

	    (@event_dispatcher_listeners[event] ||= []) << callback

	  end



	  protected

	  def notify(event, *args)

	    if @event_dispatcher_listeners[event]

	      @event_dispatcher_listeners[event].each do |m|

	        m.call(*args) if m.respond_to? :call

	      end

	    end

	    return nil

	  end

	end
Here's a Factory class that keeps a set of listeners. An outside object can choose to be notified every time a Factory object is created, or every time a Factory object produces a widget:
	class Factory

	  include EventDispatcher



	def initialize

	  setup_listeners

	end



	def produce_widget(color)

	  #Widget creation code goes here…

	    notify(:new_widget, color)

	  end

	end
Here's a listener class that's interested in what happens with Factory objects:
	class WidgetCounter

	  def initialize(factory)

	    @counts = Hash.new(0)

	    factory.subscribe(:new_widget) do |color|

	      @counts[color] += 1

	      puts "#{@counts[color]} #{color} widget(s) created since I started watching."

	    end

	  end

	end
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Chapter 8: Objects and Classes8
Inhaltsvorschau
Ruby is an object-oriented programming language; this chapter will show you what that really means. Like all modern languages, Ruby supports object-oriented notions like classes, inheiritance, and polymorphism. But Ruby goes further than other languages you may have used. Some languages are strict and some are permissive; Ruby is one of the most permissive languages around.
Strict languages enforce strong typing, usually at compile type: a variable defined as an array can't be used as another data type. If a method takes an array as an argument, you can't pass in an array-like object unless that object happens to be a subclass of the array class or can be converted into an array.
Ruby enforces dynamic typing, or duck typing ("if it quacks like a duck, it is a duck"). A strongly typed language enforces its typing everywhere, even when it's not needed. Ruby enforces its duck typing relative to a particular task. If a variable quacks like a duck, it is one—assuming you wanted to hear it quack. When you want "swims like a duck" instead, duck typing will enforce the swimming, and not the quacking.
Here's an example. Consider the following three classes, Duck, Goose, and DuckRecording:
	class Duck

	  def quack

	    'Quack!'

	  end



	  def swim

	    'Paddle paddle paddle…'

	  end

	end



	class Goose

	  def honk

	    'Honk!'

	  end

	  def swim

	    'Splash splash splash…'

	  end

	end



	class DuckRecording

	  def quack

	    play

	  end



	  def play

	    'Quack!'

	  end

	end
If Ruby was a strongly typed language, a method that told a Duck to quack would fail when given a DuckRecording. The following code is written in the hypothetical language Strongly-Typed Ruby; it won't work in real Ruby.
	def make_it_quack(Duck duck)

	  duck.quack

	end



	make_it_quack(Duck.new)                   # => "Quack!"

	make_it_quack(DuckRecording.new)

	# TypeException: object not of type Duck
If you were expecting a Duck, you wouldn't be able to tell a Goose to swim:
	def make_it_swim(Duck duck)

	  duck.swim

	end



	make_it_swim(Duck.new)                    # => "Paddle paddle paddle…"

	make_it_swim(Goose.new)

	# TypeException: object not of type Goose
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Managing Instance Data
Inhaltsvorschau
You want to associate a variable with an object. You may also want the variable to be readable or writable from outside the object.
Within the code for the object's class, define a variable and prefix its name with an at sign ( @). When an object runs the code, a variable by that name will be stored within the object.
An instance of the Frog class defined below might eventually have two instance variables stored within it, @name and @speaks_english:
	class Frog

	  def initialize(name)

	    @name = name

	  end



	  def speak

	    # It's a well-known fact that only frogs with long names start out

	    # speaking English.

	    @speaks_english ||= @name.size > 6

	    @speaks_english ? "Hi. I'm #{@name}, the talking frog." : 'Ribbit.'

	  end

	end



	Frog.new('Leonard').speak       # => "Hi. I'm Leonard, the talking frog."



	lucas = Frog.new('Lucas')

	lucas.speak                     # => "Ribbit."
If you want to make an instance variable readable from outside the object, call the attr_reader method on its symbol:
	lucas.name

	# NoMethodError: undefined method 'name' for #<Frog:0xb7d0327c @speaks_english=true,

	@name="Lucas">



	class Frog 

attr_reader :name

	end

	lucas.name                      # => "Lucas"
Similarly, to make an instance variable readable and writable from outside the object, call the attr_accessor method on its symbol:
	lucas.speaks_english = false

	# => NoMethodError: undefined method 'speaks_english=' for #<Frog:0xb7d0327c @speaks_

	#    english=false, @name="Lucas">



	class Frog 

attr_accessor :speaks_english

	end

	lucas.speaks_english = true

	lucas.speak                  # => "Hi. I'm Lucas, the talking frog."
Some programming languages have complex rules about when one object can directly access to another object's instance variables. Ruby has one simple rule: it's never allowed. To get or set the value of an instance variable from outside the object that owns it, you need to call an explicitly defined getter or setter method.
Basic getter and setter methods look like this:
	class Frog

	  def speaks_english

	    @speaks_english

	  end



	  def speaks_english=(value)

	    @speaks_english = value

	  end

	end
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Managing Class Data
Inhaltsvorschau
Instead of storing a bit of data along with every instance of a class, you want to store a bit of data along with the class itself.
Instance variables are prefixed by a single at sign; class variables are prefixed by two at signs. This class contains both an instance variable and a class variable:
	class Warning

	  @@translations = { :en => 'Wet Floor',

	                     :es => 'Piso Mojado' }



	  def initialize(language=:en)

	    @language = language

	  end



	  def warn

	    @@translations[@language]

	  end

	end



	Warning.new.warn                             # => "Wet Floor"

	Warning.new(:es).warn                        # => "Piso Mojado"
Class variables store information that's applicable to the class itself, or applicable to every instance of the class. They're often used to control, prevent, or react to the instantiation of the class. A class variable in Ruby acts like a static variable in Java.
Here's an example that uses a class constant and a class variable to control when and how a class can be instantiated:
	class Fate

	  NAMES = ['Klotho', 'Atropos', 'Lachesis'].freeze

	  @@number_instantiated = 0



	  def initialize

	    if @@number_instantiated >= NAMES.size

	      raise ArgumentError, 'Sorry, there are only three Fates.'

	    end

	    @name = NAMES[@@number_instantiated]

	    @@number_instantiated += 1

	    puts "I give you… #{@name}!"

	  end

	end



	Fate.new

	# I give you… Klotho!

	# => #<Fate:0xb7d2c348 @name="Klotho">



	Fate.new

	# I give you… Atropos!

	# => #<Fate:0xb7d28400 @name="Atropos">



	Fate.new

	# I give you… Lachesis!

	# => #<Fate:0xb7d22168 @name="Lachesis">



	Fate.new

	# ArgumentError: Sorry, there are only three Fates.
It's not considered good form to write setter or getter methods for class variables. You won't usually need to expose any class-wide information apart from helpful constants, and those you can expose with class constants such as NAMES above.
If you do want to write setter or getter methods for class variables, you can use the following class-level equivalents of Module#attr_reader and Module#attr_writer
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Checking Class or Module Membership
Inhaltsvorschau
You want to see if an object is of the right type for your purposes.
If you plan to call a specific method on the object, just check to see whether the object reponds to that method:
	def send_as_package(obj)

	  if obj.respond_to? :package

	    packaged = obj.package



	  else

	    $stderr.puts "Not sure how to package a #{obj.class}."

	    $stderr.puts 'Trying generic packager.'

	    package = Package.new(obj)

	  end

	  send(package)

	end
If you really can only accept objects of one specific class, or objects that include one specific module, use the is_a? predicate:
	def multiply_precisely(a, b)

	  if a.is_a? Float or b.is_a? Float



	    raise ArgumentError, "I can't do precise multiplication with floats."

	  end

	  a * b

	end



	multiply_precisely(4, 5) # => 20

	multiply_precisely(4.0, 5)

	# ArgumentError: I can't do precise multiplication with floats.
Whenever possible, you should use duck typing (Object#respond_to?) in preference to class typing (Object#is_a?). Duck typing is one of the great strengths of Ruby, but it only works if everyone uses it. If you write a method that only accepts strings, instead of accepting anything that supports to_str, then you've broken the duck typing illusion for everyone who uses your code.
Sometimes you can't use duck typing, though, or sometimes you need to combine it with class typing. Sometimes two different classes define the same method (especially one of the operators) in completely different ways. Duck typing makes it possible to silently do the right thing, but if you know that duck typing would silently do the wrong thing, a little class typing won't hurt.
Here's a method that uses duck typing to see whether an operation is supported, and class typing to cut short a possible problem before it occurs:
	def append_to_self(x)

	  unless x.respond_to? :<<

	    raise ArgumentError, "This object doesn't support the left-shift operator."

	  end

	  if x.is_a? Numeric

	    raise ArgumentError,

	    "The left-shift operator for this object doesn't do an append."

	  end

	  x << x

	end



	append_to_self('abc')                             # => "abcabc"

	append_to_self([1, 2, 3])                         # => [1, 2, 3, […]]



	append_to_self({1 => 2})

	# ArgumentError: This object doesn't support the left-shift operator.



	append_to_self(5)

	# ArgumentError: The left-shift operator for this object doesn't do an append.

	5 << 5                                      # => 160

	# That is, 5 * (2 ** 5)
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Writing an Inherited Class
Inhaltsvorschau
You want to create a new class that extends or modifies the behavior of an existing class.
If you're writing a new method that conceptually belongs in the original class, you can reopen the class and append your method to the class definition. You should only do this if your method is generally useful, and you're sure it won't conflict with a method defined by some library you include in the future.
This code adds a scramble method to Ruby's built-in String class (see Recipe 4.10 for a faster way to sort randomly):
	class String

	  def 

scramble

	    split(//).sort_by { rand }.join

	  end

	end



	"I once was a normal string.".scramble

	# => "i arg cn lnws.Ioateosma n r"
If your method isn't generally useful, or you don't want to take the risk of modifying a class after its initial creation, create a subclass of the original class. The subclass can override its parent's methods, or add new ones. This is safer because the original class, and any code that depended on it, is unaffected. This subclass of String adds one new method and overrides one existing one:
	class UnpredictableString < String

	  def scramble

	    split (//).sort_by { rand }.join

	  end



	  def inspect

	    scramble.inspect

	  end

	end

	str = UnpredictableString.new("It was a dark and stormy night.")

	# => " hsar gsIo atr tkd naaniwdt.ym"

	str

	# => "ts dtnwIktsr oydnhgi .mara aa"
All of Ruby's classes can be subclassed, though a few of them can't be usefully subclassed (see Recipe 8.18 for information on how to deal with the holdouts).
Ruby programmers use subclassing less frequently than they would in other languages, because it's often acceptable to simply reopen an existing class (even a built-in class) and attach a new method. We do this throughout this book, adding useful new methods to built-in classes rather than defining them in Kernel, or putting them in subclasses or utility classes. Libraries like Rails and Facets Core do the same.
This improves the organization of your code. But the risk is that a library you include (or a library included by one you include) will define the same method in the same built-in class. Either the library will override your method (breaking your code), or you'll override its method (breaking its code, which will break your code). There is no general solution to this problem short of adopting naming conventions, or always subclassing and never modifying preexisting classes.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Overloading Methods
Inhaltsvorschau
You want to create two different versions of a method with the same name: two methods that differ in the arguments they take.
A Ruby class can have only one method with a given name. Within that single method, though, you can put logic that branches depending on how many and what kinds of objects were passed in as arguments.
Here's a Rectangle class that represents a rectangular shape on a grid. You can instantiate a Rectangle in one of two ways: by passing in the coordinates of its top-left and bottom-left corners, or by passing in its top-left corner along with its length and width. There's only one initialize method, but you can act as though there were two.
	# The Rectangle constructor accepts arguments in either of the following forms:

	#  Rectangle.new([x_top, y_left], length, width)

	#  Rectangle.new([x_top, y_left], [x_bottom, y_right])

	class Rectangle

	  def 

initialize(*args)

	    case args.size

	    when 2

	      @top_left, @bottom_right = args

	    when 3

	      @top_left, length, width = args

	      @bottom_right = [@top_left[0] + length, @top_left[1] - width]

	    else

	      raise ArgumentError, "This method takes either 2 or 3 arguments."

	    end



	    # Perform additional type/error checking on @top_left and

	    # @bottom_right…

	  end

	end
Here's the Rectangle constructor in action:
	'

	Rectangle.new([10, 23], [14, 13])

	# => #<Rectangle:0xb7d15828 @bottom_right=[14, 13], @top_left=[10, 23]>



	Rectangle.new([10, 23], 4, 10)

	# => #<Rectangle:0xb7d0da4c @bottom_right=[14, 13], @top_left=[10, 23]>



	Rectangle.new

	# => ArgumentError: This method takes either 2 or 3 arguments.
In strongly typed languages like C++ and Java, you must often create multiple versions of the same method with different arguments. For instance, Java's StringBuffer class implements over 10 variants of its append method: one that takes a boolean, one that takes a string, and so on.
Ruby's equivalent of StringBuffer is StringIO, and its equivalent of the append method is StringIO#<<. In Ruby, that method can only be defined once, but it can take an object of any type. There's no need to write different versions of the method for taking different kinds of object. If you need to do type checking (such as making sure the object has a string representation), you put it in the method body rather than in the method definition.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Validating and Modifying Attribute Values
Inhaltsvorschau
You want to let outside code set your objects' instance variables, but you also want to impose some control over the values your variables are set to. You might want a chance to validate new values before accepting them. Or you might want to accept values in a form convenient to the caller, but transform them into a different form for internal storage.
Define your own setter method for each instance variable you want to control. The setter method for an instance variable quantity would be called quantity=. When a user issues a statement like object.quantity = 10, the method object#quantity= is called with the argument 10.
It's up to the quantity= method to decide whether the instance variable quantity should actually take the value 10. A setter method is free to raise an ArgumentException if it's passed an invalid value. It may also modify the provided value, massaging it into the canonical form used by the class. If it can get an acceptable value, its last act should be to modify the instance variable.
I'll define a class that keeps track of peoples' first and last names. It uses setter methods to enforce two somewhat parochial rules: everyone must have both a first and a last name, and everyone's first name must begin with a capital letter:
	class Name



	  # Define default getter methods, but not 

setter methods.

	  attr_reader :first, :last



	  # When someone tries to set a first name, enforce rules about it.

	  def first=(first)

	    if first == nil or first.size == 0

	      raise ArgumentError.new('Everyone must have a first name.')

	    end

	    first = first.dup

	    first[0] = first[0].chr.capitalize

	    @first = first

	  end

	  # When someone tries to set a last name, enforce rules about it.

	  def last=(last)

	    if last == nil or last.size == 0

	      raise ArgumentError.new('Everyone must have a last name.')

	    end

	    @last = last

	  end



	  def full_name

	    "#{@first} #{@last}"

	  end

	

	  # Delegate to the setter methods instead of setting the instance

	  # variables directly.

	  def initialize(first, last)

	    self.first = first

	    self.last = last

	  end

	end
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Defining a Virtual Attribute
Inhaltsvorschau
You want to create accessor methods for an attribute that isn't directly backed by any instance variable: it's a calculated value derived from one or more different instance variables.
Define accessor methods for the attribute in terms of the instance variables that are actually used. There need not be any relationship between the names of the accessor methods and the names of the instance variables.
The following class exposes four accessor methods: degrees, degrees=, radians, and radians=. But it only stores one instance variable: @radians.
	class Arc

	  attr_accessor :radians



	  def degrees

	    @radians * 180 / Math::PI

	  end



	  def degrees=(degrees)

	    @radians = degrees * Math::PI / 180

	  end

	end



	arc = Arc.new

	arc.degrees = 180

	arc.radians                                # => 3.14159265358979

	arc.radians = Math::PI / 2

	arc.degrees                                # => 90.0
Ruby accessor methods usually correspond to the names of the instance variables they access, but this is nothing more than a convention. Outside code has no way of knowing what your instance variables are called, or whether you have any at all, so you can create accessors for virtual attributes with no risk of outside code thinking they're backed by real instance variables.
  • Recipe 2.9, "Converting Between Degrees and Radians"
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Delegating Method Calls to Another Object
Inhaltsvorschau
You'd like to delegate some of an object's method calls to a different object, or make one object capable of " impersonating" another.
If you want to completely impersonate another object, or delegate most of one object's calls to another, use the delegate library. It generates custom classes whose instances can impersonate objects of any other class. These custom classes respond to all methods of the class they shadow, but they don't do any work of their own apart from calling the same method on some instance of the "real" class.
Here's some code that uses delegate to generate CardinalNumber, a class that acts almost like a Fixnum. CardinalNumber defines the same methods as Fixnum does, and it takes a genuine Fixnum as an argument to its constructor. It stores this object as a member, and when you call any of Fixnum's methods on a CardinalNumber object, it delegates that method call to the stored Fixnum. The only major exception is the to_s method, which I've decided to override.
	require 'delegate'



	# An integer represented as an ordinal number (1st, 2nd, 3rd…), as

	# opposed to an ordinal number (1, 2, 3…) Generated by the

	# DelegateClass to have all the methods of the Fixnum class.

	class OrdinalNumber < DelegateClass(Fixnum)

	  def to_s

	    delegate_s = __getobj_ _.to_s

	    check = abs

	    if to_check == 11 or to_check == 12

	      suffix = "th"

	    else

	      case check % 10

	        when 1 then suffix = "st"

	        when 2 then suffix = "nd"

	        else suffix = "th"

	      end

	    end

	    return delegate_s + suffix

	  end

	end



	4.to_s # => "4"

	OrdinalNumber.new(4).to_s                    # => "4th"



	OrdinalNumber.new(102).to_s                  # => "102nd"

	OrdinalNumber.new(11).to_s                   # => "11th"

	OrdinalNumber.new(-21).to_s                  # => "-21st"



	OrdinalNumber.new(5).succ                    # => 6

	OrdinalNumber.new(5) + 6                     # => 11

	OrdinalNumber.new(5) + OrdinalNumber.new(6)  # => 11
The delegate library is useful when you want to extend the behavior of objects you don't have much control over. Usually these are objects you're not in charge of instantiating—they're instantiated by factory methods, or by Ruby itself. With
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Converting and Coercing Objects to Different Types
Inhaltsvorschau
You have an object of one type and you want to use it as though it were of another type.
You might not have to do anything at all. Ruby doesn't enforce type safety unless the programmer has explicitly written it in. If your original class defines the same methods as the class you were thinking of converting it to, you might be able to use your object as is.
If you do have to convert from one class to another, Ruby provides conversion methods for most common paths:
	"4".to_i                                              # => 4

	4.to_s                                                # => "4"

	Time.now.to_f                                         # => 1143572140.90932

	{ "key1" => "value1", "key2" => "value2" }.to_a

	# => [["key1", "value1"], ["key2", "value2"]]
If all else fails, you might be able to manually create an instance of the new class, and set its instance variables using the old data.
Some programming languages have a "cast" operator that forces the compiler to treat an object of one type like an object of another type. A cast is usually a programmer's assertion that he knows more about the types of objects than the compiler. Ruby has no cast operator. From Ruby's perspective, type checking is just an extra hoop you have to jump through. A cast operator would make it easier to jump through that hoop, but Ruby omits the hoop altogether.
Wherever you're tempted to cast an object to another type, you should be able to just do nothing. If your object can be used as the other type, there's no problem: if not, then casting it to that type wouldn't have helped anyway.
Here's a concrete example. You probably don't need to convert a hash into an array just so you can pass it into an iteration method that expects an array. If that method only calls each on its argument, it doesn't really "expect an array:" it expects a reasonable implementation of each. Ruby hashes provide that implementation just as well as arrays.
	def print_each(array)

	  array.each { |x| puts x.inspect }

	end



	hash = { "pickled peppers" => "peck of",

	         "sick sheep"      => "sixth" }

	print_each(hash.to_a)

	# ["sick sheep", "sixth"]

	# ["pickled peppers", "peck of"]



	print_each(hash)

	# ["sick sheep", "sixth"]

	# ["pickled peppers", "peck of"]
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Getting a Human-Readable Printout of Any Object
Inhaltsvorschau
You want to look at a natural-looking rendition of a given object.
Use Object#inspect. Nearly all the time, this method will give you something more readable than simply printing out the object or converting it into a string.
	a = [1,2,3]

	puts a

	# 1

	# 2

	# 3



	puts a.to_s

	# 123



	puts a.inspect

	# [1, 2, 3]

	puts /foo/

	# (?-mix:foo)

	puts /foo/.inspect

	# /foo/

	f = File.open('foo', 'a')

	puts f

	# #<File:0xb7c31c30>

	puts f.inspect

	# #<File:foo>
Even very complex data structures can be inspected and come out looking just like they would in Ruby code to define that data structure. In some cases, you can even run the output of inspect through eval to recreate the object.
	periodic_table = [{ :symbol => "H", :name => "hydrogen", :weight => 1.007 },

	                  { :symbol => "Rg", :name => "roentgenium", :weight => 272 }]

	puts periodic_table.inspect

	# [{:symbol=>"H", :name=>"hydrogen", :weight=>1.007},

	# {:symbol=>"Rg", :name=>"roentgenium", :weight=>272}]



	eval(periodic_table.inspect)[0]

	# => {:symbol=>"H", :name=>"hydrogen", :weight=>1.007}
By default, an object's inspect method works the same way as its to_s method. Unless your classes override inspect, inspecting one of your objects will yield a boring and not terribly helpful string, containing only the object's class name, object_id, and instance variables:
	class Dog

	  def initialize(name, age)

	    @name = name

	    @age = age * 7 #Compensate for dog years

	  end

	end



	spot = Dog.new("Spot", 2.1)

	spot.inspect

	# => "#<Dog:0xb7c16bec @name="Spot", @age=14.7>"
That's why you'll help out your future self by defining useful inspect methods that give relevant information about the objects you'll be instantiating.
	class Dog

	  def inspect

	    "<A Dog named #{@name} who's #{@age} in dog years.>"

	  end

	  def to_s

	    inspect

	  end

	end

	spot.inspect

	# => "<A Dog named Spot who's 14.7 in dog years.>"
Or, if you believe in being able to eval the output of inspect:
	class Dog

	  def inspect

	    %{Dog.new("#{@name}", #{@age/7})}

	  end

	end

	spot.inspect

	# => "Dog.new("Spot", 2.1)"

	eval(spot.inspect).inspect

	# => "Dog.new("Spot", 2.1)"
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Accepting or Passing a Variable Number of Arguments
Inhaltsvorschau
You want to write a method that can accept any number of arguments. Or maybe you want to pass the contents of an array as arguments into such a method, rather than passing in the array itself as a single argument.
To accept any number of arguments to your method, prefix the last argument name with an asterisk. When the method is called, all the "extra" arguments will be collected in a list and passed in as that argument:
	def sum(*numbers)

	  puts "I'm about to sum the array #{numbers.inspect}"

	  numbers.inject(0) { |sum, x| sum += x }

	end



	sum(1, 2, 10)

	# I'm about to sum the array [1, 2, 10]

	# => 13



	sum(2, -2, 2, -2, 2, -2, 2, -2, 2)

	# I'm about to sum the array [2, -2, 2, -2, 2, -2, 2, -2, 2]

	# => 2

	

	sum

	# I'm about to sum the array []

	# => 0
To pass an array of arguments into a method, use the asterisk signifier before the array you want to be turned into "extra" arguments:
	to_sum = []

	1.upto(10) { |x| to_sum << x }

	sum(*to_sum)

	# I'm about to sum the array [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

	# => 55
Bad things happen if you forget the asterisk: your entire array is treated as a single "extra" argument:
	sum(to_sum)

	# I'm about to sum the array [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]]

	# TypeError: Array can't be coerced into Fixnum
Why make a method take a variable number of arguments, instead of just having it take a single array? It's basically for the convenience of the user. Consider the Kernel#printf method, which takes one fixed argument (a format string), and then a variable number of inputs to the format string:
	printf('%s | %s', 'left', 'right')

	# left | right
It's very rare that the caller of printf already has her inputs lying around in an array. Fortunately, Ruby is happy to create the array on the user's behalf. If the caller does already have an array of inputs, it's easy to pass the contents of that array as "extra" arguments by sticking the asterisk onto the appropriate variable name:
	inputs = ['left', 'right']

	printf('%s | %s', *inputs)

	# left | right
As you can see, a method can take a fixed number of "normal" arguments and then a variable number of "extra" arguments. When defining such a method, just make sure that the last argument is the one you prefix with the asterisk:
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Simulating Keyword Arguments
Inhaltsvorschau
A function or method can accept many optional arguments. You want to let callers pass in only the arguments they have values for, but Ruby doesn't support keyword arguments as Python and Lisp do.
Write your function to accept as its final argument a map of symbols to values. Consult the map as necessary to see what arguments were passed in.
	def fun_with_text(text, args={})

	  text = text.upcase if args[:upcase]

	  text = text.downcase if args[:downcase]

	  if args[:find] and args[:replace]

	    text = text.gsub(args[:find], args[:replace])

	  end

	  text = text.slice(0, args[:truncate_at]) if args[:truncate_at]

	  return text

	end
Ruby has syntactic sugar that lets you define a hash inside a function call without putting it in curly brackets. This makes the code look more natural:
	fun_with_text("Foobar", {:upcase => true, :truncate_at => 5})

	# => "FOOBA"

	fun_with_text("Foobar", :upcase => true, :truncate_at => 5)

	# => "FOOBA"

	fun_with_text("Foobar", :find => /(o+)/, :replace => '\1d', :downcase => true)

	# => "foodbar"
This simple code works well in most cases, but it has a couple of shortcomings compared to "real" keyword arguments. These simulated keyword arguments don't work like regular arguments because they're hidden inside a hash. You can't reject an argument that's not part of the "signature," and you can't force a caller to provide a particular keyword argument.
Each of these problems is easy to work around (for instance, does a required argument really need to be a keyword argument?), but it's best to define the workaround code in a mixin so you only have to do it once. The following code is based on a KeywordProcessor module by Gavin Sinclair:
	###

	# This mix-in module lets methods match a caller's hash of keyword

	# parameters against a hash the method keeps, mapping keyword

	# arguments to default parameter values.

	#

	# If the caller leaves out a keyword parameter whose default value is

	# :MANDATORY (a constant in this module), then an error is raised.

	#

	# If the caller provides keyword parameters which have no

	# corresponding keyword arguments, an error is raised.

	#

	module KeywordProcessor

	  MANDATORY = :MANDATORY



	  def process_params(params, defaults)

	    # Reject params not present in defaults.

	    params.keys.each do |key|

	      unless defaults.has_key? key

	        raise ArgumentError, "No such keyword argument: #{key}"

	      end

	    end

	    result = defaults.dup.update(params)



	    # Ensure mandatory params are given.

	    unfilled = result.select { |k,v| v == MANDATORY }.map { |k,v| k.inspect }

	    unless unfilled.empty?

	      msg = "Mandatory keyword parameter(s) not given: #{unfilled.join(', ')}"

	      raise ArgumentError, msg

	    end



	    return result

	  end

	end
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Calling a Superclass's Method
Inhaltsvorschau
When overriding a class's method in a subclass, you want to extend or decorate the behavior of the superclass, rather than totally replacing it.
Use the super keyword to call the superclass implementation of the current method.
When you call super with no arguments, the arguments to your method are passed to the superclass method exactly as they were recieved by the subclass. Here's a Recipe class that defines (among other things) a cook method.
	class Recipe

	  # … The rest of the Recipe implementation goes here.

	  def cook(stove, cooking_time)

	    dish = prepare_ingredients

	    stove << dish

	    wait_for(cooking_time)

	    return dish

	  end

	end
Here's a subclass of Recipe that tacks some extra behavior onto the recipe. It passes all of its arguments directly into super:
	class RecipeWithExtraGarlic < Recipe

	  def cook(stove, cooking_time)



	    5.times { add_ingredient(Garlic.new.chop) }

	    super

	  end

	end
A subclass implementation can also choose to pass arguments into super. This way, a subclass can accept different arguments from its superclass implementation:
	class BakingRecipe < Recipe

	  def cook(cooking_time, oven_temperature=350)

	    oven = Oven.new(oven_temperature)

	    super(oven, cooking_time)

	  end

	end
You can call super at any time in the body of a method—before, during, or after calling other code. This is in contrast to languages like Java, where you must call super in the method's first statement or never call it at all. If you need to, you can even call super multiple times within a single method.
Often you want to create a subclass method that exposes exactly the same interface as its parent. You can use the *args constructor to make the subclass method accept any arguments at all, then call super with no arguments to pass all those arguments (as well as any attached code block) into the superclass implementation. Let the superclass deal with any problems with the arguments.
The String#gsub method exposes a fairly complicated interface, but the String subclass defined here doesn't need to know anything about it:
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Creating an Abstract Method
Inhaltsvorschau
You want to define a method of a class, but leave it for subclasses to fill in the actual implementations.
Define the method normally, but have it do nothing except raise a NotImplementedError:
	class Shape2D

	  def area

	    raise NotImplementedError.

	    new("#{self.class.name}#area is an 

abstract method.")

	  end

	end



	Shape2D.new.area

	# NotImplementedError: Shape2D#area is an  

abstract method.
A subclass can redefine the method with a concrete implementation:
	class Square < Shape2D

	  def initialize(length)

	    @length = length

	  end



	  def area

	    @length ** 2

	  end

	end



	Square.new(10).area 	                     # => 100
Ruby doesn't have a built-in notion of an abstract method or class, and though it has many built-in classes that might be considered "abstract," it doesn't enforce this abstractness the way C++ and Java do. For instance, you can instantiate an instance of Object or Numeric, even though those classes don't do anything by themselves.
In general, this is in the spirit of Ruby. But it's sometimes useful to define a superclass method that every subclass is expected to implement. The NotImplementedError error is the standard way of conveying that a method is not there, whether it's abstract or just an unimplemented stub.
Unlike other programming languages, Ruby will let you instantiate a class that defines an abstract method. You won't have any problems until you actually call the abstract method; even then, you can catch the NotImplementedError and recover. If you want, you can make an entire class abstract by making its initialize method raise a NotImplementedError. Then no one will be able to create instances of your class:
	class Shape2D

	  def initialize

	   raise NotImplementedError.

	    new("#{self.class.name} is an abstract class.")

	  end

	end



	Shape2D.new

	# NotImplementedError: Shape2D is an abstract class.
We can do the same thing in less code by defining a decorator method of Class that creates an abstract method by the given name.
	class Class

	  def 

abstract(*args)

	    args.each do |method_name|

	

	      define_method(method_name) do |*args|

	        if method_name == :initialize

	          msg = "#{self.class.name} is an abstract class."

	        else

	          msg = "#{self.class.name}##{method_name} is an abstract method."

	        end

	        raise NotImplementedError.new(msg)



	     end

	    end

	  end

	end
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Freezing an Object to Prevent Changes
Inhaltsvorschau
You want to prevent any further changes to the state of an object.
Freeze the object with Object#freeze:
	frozen_string = 'Brrrr!'

	frozen_string.freeze

	frozen_string.gsub('r', 'a')                     # => "Baaaa!"

	frozen_string.gsub!('r', 'a')

	# TypeError: can't modify frozen string
When an object is frozen, its instance variables are permanently bound to their current values. The values themselves are not frozen: their instance variables can still be modified, to the extent they were modifiable before:
	sequences = [[1,2,3], [1,2,4], [1,4,9]].freeze

	sequences << [2,3,5]

	# TypeError: can't modify frozen array

	sequences[2] << 16                         # => [1, 4, 9, 16]
A frozen object cannot be unfrozen, and if cloned, the clone will also be frozen. Calling Object#dup (as opposed to Object#clone) on a frozen object yields an unfrozen object with the same instance variables.
	frozen_string.clone.frozen?                      # => true

	frozen_string.dup.frozen?                        # => false
Freezing an object does not prevent reassignment of any variables bound to that object.
	frozen_string = 'A new string.'

	frozen_string.frozen?                            # => false
To prevent objects from changing in ways confusing to the user or to the Ruby interpreter, Ruby sometimes copies objects and freezes the copies. When you use a string as a hash key, Ruby actually copies the string, freezes the copy, and uses the copy as the hash key: that way, if the original string changes later on, the hash key isn't affected.
Constant objects are often frozen as a second line of defense against the object being modified in place. You can freeze an object whenever you need a permanent reference to an object; this is most commonly seen with strings:
	API_KEY = "100f7vo4gg".freeze



	API_KEY[0] = 4

	# TypeError: can't modify frozen string



	API_KEY = "400f7vo4gg"

	# warning: already initialized constant API_KEY
Frozen objects are also useful in multithreaded code. For instance, Ruby's internal file operations work from a frozen copy of a filename instead of using the filename directly. If another thread modifies the original filename in the middle of an operation that's supposed to be atomic, there's no problem: Ruby wasn't relying on the original filename anyway. You can adopt this copy-and-freeze pattern in multithreaded code to prevent a data structure you're working on from being changed by another thread.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Making a Copy of an Object
Inhaltsvorschau
You want to make a copy of an existing object: a new object that can be modified separately from the original.
Ruby provides two ways of doing this. If you only want to have to remember one way, remember Object#clone:
	s1 = 'foo'                             # => "foo"

	s2 = s1.clone                          # => "foo"

	s1[0] = 'b'

	[s1, s2]                               # => ["boo", "foo"]
Ruby has two object-copy methods: a quick one and a thorough one. The quick one, Object#dup, creates a new instance of an object's class, then sets all of the new object's instance variables so that they reference the same objects as the original does. Finally, it makes the new object tainted if the old object was tainted.
The downside of dup is that it creates a new instance of the object's original class. If you open up a specific object and give it a singleton method, you implicitly create a metaclass, an anonymous subclass of the original class. Calling dup on the object will yield a copy that lacks the singleton methods. The other object-copy method, Object#clone, makes a copy of the metaclass and instantiates the copy, instead of instantiating the object's original class.
	material = 'cotton'

	class << material

	  def definition

	     puts 'The better half of velour.'

	  end

	end

	

	material.definition

	# The better half of velour.



	'cotton'.definition

	# NoMethodError: undefined method 'definition' for "cotton":String



	material.clone.definition

	# The better half of velour.



	material.dup.definition

	# NoMethodError: undefined method 'definition' for "cotton":String
Object#clone is also more strict about propagating Ruby's internal flags: it will propagate both an object's "tainted?" flag and its "frozen?" flag. If you want to make an unfrozen copy of a frozen object, you must use Object#dup.
Object#clone and Object#dup both perform shallow copies: they make copies of an object without also copying its instance variables. You'll end up with two objects whose instance variables point to the same objects. Modifications to one object's instance variables will be visible in the other object. This can cause problems if you're not expecting it:
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Declaring Constants
Inhaltsvorschau
You want to prevent a variable from being assigned a different value after its initial definition.
Declare the variable as a constant. You can't absolutely prohibit the variable from being assigned a different value, but you can make Ruby generate a warning whenever that happens.
	not_a_constant = 3

	not_a_constant = 10



	A_CONSTANT = 3

	A_CONSTANT = 10

	# warning: already initialized constant A_CONSTANT
A constant variable is one whose name starts with a capital letter. By tradition, Ruby constant names consist entirely of capital letters, numbers, and underscores. Constants don't mesh well with Ruby's philosophy of unlimited changability: there's no way to absolutely prevent someone from changing your constant. However, they are a useful signal to the programmers who come after you, letting them know not to redefine a constant without a very good reason.
Constants can occur anywhere in code. If they appear within a class or module, you can access them from outside the class or module with the double-colon operator ( ::). The name of the class or module qualifies the name of the constant, preventing confusion with other constants that may have the same name but be defined in different scopes.
	CONST = 4



	module ConstModule

	  CONST = 6

	end



	class ConstHolder

	  CONST = 8



	  def my_const

	    return CONST

	  end

	end



	CONST                                  # => 4

	ConstModule::CONST                     # => 6

	ConstHolder::CONST                     # => 8

	ConstHolder.new.my_const               # => 8
The thing that's constant about a constant is its reference to an object. If you change the reference to point to a different object, you'll get a warning. Unfortunately, there's no way to tell Ruby to treat the redeclaration of a constant as an error.
	E = 2.718281828                        # => 2.718281828

	E = 6                                  # warning: already initialized constant E

	E                                      # => 6
However, you can use Module#remove_const as a sneaky way to "undeclare" a constant. You can then declare the constant again, without even triggering a warning. Clearly, this is potent and potentially dangerous stuff:
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Implementing Class and Singleton Methods
Inhaltsvorschau
You want to associate a new method with a class (as opposed to the instances of that class), or with a particular object (as opposed to other instances of the same class).
To define a class method, prefix the method name with the class name in the method definition. You can do this inside or outside of the class definition.
The Regexp.is_valid? method, defined below, checks whether a string can be compiled into a regular expression. It doesn't make sense to call it on an already instantiated Regexp, but it's clearly related functionality, so it belongs in the Regexp class (assuming you don't mind adding a method to a core Ruby class).
	class Regexp

	  def Regexp.is_valid?(str)

	    begin

	      compile(str)

	      valid = true

	    rescue RegexpError

	      valid = false

	    end

	  end

	end

	Regexp.is_valid? "The horror!"             # => true

	Regexp.is_valid? "The)horror!"             # => false
Here's a Fixnum.random method that generates a random number in a specified range:
	def Fixnum.random(min, max)

	  raise ArgumentError, "min > max" if min > max

	  return min + rand(max-min+1)

	end

	Fixnum.random(10, 20)                                  # => 13

	Fixnum.random(-5, 0)                                   # => -5

	Fixnum.random(10, 10)                                  # => 10

	Fixnum.random(20, 10)

	# ArgumentError: min > max
To define a method on one particular other object, prefix the method name with the variable name when you define the method:
	company_name = 'Homegrown Software'

	def company_name.legalese

	  return "#{self} is a registered trademark of ConglomCo International."

	end



	company_name.legalese

	# => "Homegrown Software is a registered trademark of ConglomCo International."

	'Some Other Company'.legalese

	# NoMethodError: undefined method 'legalese' for "Some Other Company":String
In Ruby, a singleton method is a method defined on one specific object, and not available to other instances of the same class. This is kind of analagous to the Singleton pattern, in which all access to a certain class goes through a single instance, but the name is more confusing than helpful.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Controlling Access by Making Methods Private
Inhaltsvorschau
You've refactored your code (or written it for the first time) and ended up a method that should be marked for internal use only. You want to prevent outside objects from calling such methods.
Use private as a statement before a method definition, and the method will not be callable from outside the class that defined it. This class defines an initializer, a public method, and a private method:
	class SecretNumber

	  def initialize

	    @secret = rand(20)

	  end

	  def hint

	    puts "The number is #{"not " if secret <= 10}greater than 10."

	  end 

private

	  def secret

	    @secret

	  end

	end



	s = SecretNumber.new

	s.secret

	# NoMethodError:  

private method 'secret' called for

	# #<SecretNumber:0xb7c2e83c @secret=19>



	s.hint

	# The number is greater than 10.
Unlike in many other programming languages, a private method in Ruby is accessible to subclasses of the class that defines it:
	class LessSecretNumber < SecretNumber

	  def hint

	    lower = secret-rand(10)-1

	    upper = secret+rand(10)+1

	    "The number is somewhere between #{lower} and #{upper}."

	  end

	end



	ls = LessSecretNumber.new

	ls.hint

	# => "The number is somewhere between -3 and 16."

	ls.hint

	# => "The number is somewhere between -1 and 15."

	ls.hint

	# => "The number is somewhere between -2 and 16."
Like many parts of Ruby that look like special language features, Ruby's privacy keywords are actually methods. In this case, they're methods of Module. When you call private, protected, or public, the current module (remember that a class is just a special kind of module) changes the rules it applies to newly defined methods from that point on.
Most languages that support method privacy make you put a keyword before every method saying whether it's public, private, or protected. In Ruby, the special privacy methods act as toggles. When you call the private keyword, all methods you define after that point are declared as private, until the module definition ends or you call a different privacy method. This makes it easy to group methods of the same privacy level—a good, general programming practice:
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Chapter 9: Modules and Namespaces
Inhaltsvorschau
A Ruby module is nothing more than a grouping of objects under a single name. The objects may be constants, methods, classes, or other modules.
Modules have two uses. You can use a module as a convenient way to bundle objects together, or you can incorporate its contents into a class with Ruby's include statement.
When a module is used as a container for objects, it's called a namespace. Ruby's Math module is a good example of a namespace: it provides an overarching structure for constants like Math::PI and methods like Math::log, which would otherwise clutter up the main Kernel namespace. We cover this most basic use of modules in Recipes 9.5 and 9.7.
Modules are also used to package functionality for inclusion in classes. The Enumerable module isn't supposed to be used on its own: it adds functionality to a class like Array or Hash. We cover the use of modules as packaged functionality for existing classes in Recipes 9.1 and 9.4.
Module is actually the superclass of Class, so every Ruby class is also a module. Throughout this book we talk about using methods of Module from within classes. The same methods will work exactly the same way within modules. The only thing you can't do with a module is instantiate an object from it:
	Class.superclass    # => Module

	Math.class          # => Module

	Math.new

	# NoMethodError: undefined method `new' for Math:Module
You want to create a class that derives from two or more sources, but Ruby doesn't support multiple inheritance.
Suppose you created a class called Taggable that lets you associate tags (short strings of informative metadata) with objects. Every class whose objects should be taggable could derive from Taggable.
This would work if you made Taggable the top-level class in your class structure, but that won't work in every situation. Eventually you might want to do something like make a string taggable. One class can't subclass both Taggable and String, so you'd have a problem.
Furthermore, it makes little sense to instantiate and use a Taggable object by itself—there is nothing there to tag! Taggability is more of a feature of a class than a fullfledged class of its own. The
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Simulating Multiple Inheritance with Mixins
Inhaltsvorschau
You want to create a class that derives from two or more sources, but Ruby doesn't support multiple inheritance.
Suppose you created a class called Taggable that lets you associate tags (short strings of informative metadata) with objects. Every class whose objects should be taggable could derive from Taggable.
This would work if you made Taggable the top-level class in your class structure, but that won't work in every situation. Eventually you might want to do something like make a string taggable. One class can't subclass both Taggable and String, so you'd have a problem.
Furthermore, it makes little sense to instantiate and use a Taggable object by itself—there is nothing there to tag! Taggability is more of a feature of a class than a fullfledged class of its own. The Taggable functionality only works in conjunction with some other data structure.
This makes it an ideal candidate for implementation as a Ruby module instead of a class. Once it's in a module, any class can include it and use the methods it defines.
	require 'set' # Deals with a collection of unordered values with no duplicates



	# Include this module to make your class taggable. The names of the

	# instance variable and the setup method are prefixed with "taggable_"

	# to reduce the risk of namespace collision. You must call

	# taggable_setup before you can use any of this module's methods.

	module Taggable

	  attr_accessor :tags



	  def taggable_setup

	    @tags = Set.new

	  end



	  def add_tag(tag)

	    @tags << tag

	  end



	  def remove_tag(tag)

	    @tags.delete(tag)

	  end

	end
Here's a taggable string class: it subclasses String, but it also includes the functionality of Taggable.
	class TaggableString < String

	  include Taggable

	  def initialize(*args)

	    super

	    taggable_setup

	  end

	end

	s = TaggableString.new('It was the best of times, it was the worst of times.')

	s.add_tag 'dickens'

	s.add_tag 'quotation'

	s.tags # =>                       #<Set: {"dickens", "quotation"}>
A Ruby class can only have one superclass, but it can include any number of modules. These modules are called
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Extending Specific Objects with Modules
Inhaltsvorschau
Credit: Phil Tomson
You want to add instance methods from a module (or modules) to specific objects. You don't want to mix the module into the object's class, because you want certain objects to have special abilities.
Use the Object#extend method.
For example, let's say we have a mild-mannered Person class:
	class Person

	  attr_reader :name, :age, :occupation



	   def initialize(name, age, occupation)

	     @name, @age, @occupation = name, age, occupation

	   end



	   def mild_mannered?

	     true

	   end

	end
Now let's create a couple of instances of this class.
	jimmy = Person.new('Jimmy Olsen', 21, 'cub reporter')

	clark = Person.new('Clark Kent', 35, 'reporter')

	jimmy.mild_mannered?                        # => true 

	clark.mild_mannered?                        # => true
But it happens that some Person objects are not as mild-mannered as they might appear. Some of them have super powers.
	module SuperPowers

	  def fly

	    'Flying!'

	  end



	  def leap(what)

	     "Leaping #{what} in a single bound!"

	  end



	  def mild_mannered?

	     false

	  end



	  def superhero_name

	    'Superman'

	  end

	end
If we use include to mix the SuperPowers module into the Person class, it will give every person super powers. Some people are bound to misuse such power. Instead, we'll use extend to give super powers only to certain people:
	clark.extend(SuperPowers)

	clark.superhero_name                   # => "Superman"

	clark.fly                              # => "Flying!"

	clark.mild_mannered?                   # => false

	jimmy.mild_mannered?                   # => true
The extend method is used to mix a module's methods into an object, while include is used to mix a module's methods into a class.
The astute reader might point out that classes are actually objects in Ruby. Let us see what happens when we use extend in a class definition:
	class Person 

	  extend SuperPowers 

	end



	#which is equivalent to:

	Person.extend(SuperPowers)
What exactly are we extending here? Within the class definition,
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Mixing in Class Methods
Inhaltsvorschau
Credit: Phil Tomson
You want to mix class methods into a class, instead of mixing in instance methods.
The simplest way to accomplish this is to call extend on the class object, as seen in the Discussion of Recipe 9.2. Just as you can use extend to add singleton methods to an object, you can use it to add class methods to a class. But that's not always the best option. Your users may not know that your module provides or even requires some class methods, so they might not extend their class when they should. How can you make an include statement mix in class methods as well?
To begin, within your module, define a submodule called ClassMethods,which contains the methods you want to mix into the class:
	module MyLib

	  module ClassMethods

	    def class_method

	      puts "This method was first defined in MyLib::ClassMethods"

	    end

	  end

	end
To make this code work, we must also define the included callback method within the MyLib module. This method is called every time a module is included in the class, and it's passed the class object in which our module is being included. Within the callback method, we extend that class object with our ClassMethods module, making all of its instance methods into class methods. Continuing the example:
	module MyLib

	  def self.included(receiver)

	    puts "MyLib is being included in #{receiver}!"

	    receiver.extend(ClassMethods)

	  end

	end
Now we can include our MyLib module in a class, and get the contents of ClassMethods mixed in as genuine class methods:
	class MyClass

	  include MyLib

	end

	# MyLib is being included in MyClass!



	MyClass.class_method

	# This method was first defined in MyLib::ClassMethods
Module#included is a callback method that is automatically called during the inclusion of a module into a class. The default included implementation is an empty method. In the example, MyLib overrides it to extend the class that's including the MyLib module with the contents of the MyLib::ClassMethods submodule.
The
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Implementing Enumerable: Write One Method, Get 22 Free
Inhaltsvorschau
You want to give a class all the useful iterator and iteration-related features of Ruby's arrays (sort, detect, inject, and so on), but your class can't be a subclass of Array. You don't want to define all those methods yourself.
Implement an each method, then include the Enumerable module. It defines 22 of the most useful iteration methods in terms of the each implementation you provide.
Here's a class that keeps multiple arrays under the covers. By defining each, it can expose a large interface that lets the user treat it like a single array:
	class MultiArray

	  include Enumerable



	  def initialize(*arrays)

	    @arrays = arrays

	  end



	  def each

	    @arrays.each { |a| a.each { |x| yield x } }

	  end

	end



	ma = MultiArray.new([1, 2], [3], [4])

	ma.collect                                        # => [1, 2, 3, 4]

	ma.detect { |x| x > 3 }                        # => 4

	ma.map { |x| x ** 2 }                             # => [1, 4, 9, 16]

	ma.each_with_index { |x, i| puts "Element #{i} is #{x}" }

	# Element 0 is 1

	# Element 1 is 2

	# Element 2 is 3

	# Element 3 is 4
The Enumerable module is the most common mixin module. It lets you add a lot of behavior to your class for a little investment. Since Ruby relies so heavily on iterator methods, and almost every data structure can be iterated over in some way, it's no wonder that so many of the classes in Ruby's standard library include Enumerable: Dir, Hash, Range, and String, just to name a few.
Here's the complete list of methods you can get by including Enumerable. Many of them are described elsewhere in this book, especially in Chapter 4. Perhaps the most useful are collect, inject, find_all, and sort_by.
	Enumerable.instance_methods.sort

	# => ["all?", "any?", "collect", "detect", "each_with_index", "entries",

	# => "find", "find_all", "grep", "include?", "inject", "map", "max",

	# => "member?", "min", "partition", "reject", "select", "sort", "sort_by",

	# => "to_a", "zip"]
Although you can get all these methods simply by implementing an
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Avoiding Naming Collisions with Namespaces
Inhaltsvorschau
You want to define a class or module whose name conflicts with an existing class or module, or you want to prevent someone else from coming along later and defining a class whose name conflicts with yours.
A Ruby module can contain classes and other modules, which means you can use it as a namespace.
Here's some code from a physics library that defines a class called String within the StringTheory module. The real name of this class is its fully-qualified name: StringTheory::String. It's a totally different class from Ruby's built-in String class.
	module StringTheory

	  class String

	    def initialize(length=10**-33)

	      @length = length

	    end

	  end

	end



	String.new                                    # => ""



	StringTheory::String.new

	# => #<StringTheory::String:0xb7c343b8 @length=1.0e-33>
If you've read Recipe 8.17, you've already seen namespaces in action. The constants defined in a module are qualified with the module's name. This lets Math::PI have a different value from Greek::PI.
You can qualify the name of any Ruby object this way: a variable, a class, or even another module. Namespaces let you organize your libraries, and make it possible for them to coexist alongside others.
Ruby's standard library uses namespaces heavily as an organizing principle. An excellent example is REXML, the standard XML library. It defines a REXML namespace that includes lots of XML-related classes like REXML::Comment and REXML::Instruction. Naming those classes Comment and Instruction would be a disaster: they'd get overwritten by other librarys' Comment and Instruction classes. Since nothing about the genericsounding names relates them to the REXML library, you might look at someone else's code for a long time before realizing that the Comment objects have to do with XML.
Namespaces can be nested: see for instance rexml's REXML::Parsers module, which contains classes like REXML::Parsers::StreamParser. Namespaces group similar classes in one place so you can find what you're looking for; nested namespaces do the same for namespaces.
In Ruby, you should name your top-level module after your software project (
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Automatically Loading Libraries as Needed
Inhaltsvorschau
You've written a big library with multiple components. You'd like to split it up so that users don't have to load the entire library into memory just to use part of it. But you don't want to make your users explicitly require each part of the library they plan to use.
Split the big library into multiple files, and set up autoloading for the individual files by calling Kernel#autoload. The individual files will be loaded as they're referenced.
Suppose you have a library, functions.rb, that provides two very large modules:
	# functions.rb

	module Decidable

	  # … Many, many methods go here.

	end



	module Semidecidable

	  # … Many, many methods go here.

	end
You can provide the same interface, but possibly save your users some memory, by splitting functions.rb into three files. The functions.rb file itself becomes a stub full of autoload calls:
	# functions.rb

	autoload :Decidable, "decidable.rb"

	autoload :Semidecidable, "semidecidable.rb"
The modules themselves go into the files mentioned in the new functions.rb:
	# decidable.rb

	module Decidable

	  # … Many, many methods go here.

	end

	# semidecidable.rb

	module Semidecidable

	  # … Many, many methods go here.

	end
The following code will work if all the modules are in functions.rb, but it will also work if functions.rb only contains calls to autoload:
	require 'functions'

	Decidable.class                                           # => Module

	# More use of the Decidable module follows…
When Decidable and Semidecidable have been split into autoloaded modules, that code only loads the Decidable module. Memory is saved that would otherwise be used to contain the unsed Semidecidable module.
Refactoring a library to consist of autoloadable components takes a little extra planning, but it's often worth it to improve performance for the people who use your library.
Each call to Kernel#autoload binds a symbol to the path of the Ruby file that's supposed to define that symbol. If the symbol is referenced, that file is loaded exactly as though it had been passed as an argument into require
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Including Namespaces
Inhaltsvorschau
You want to use the objects within a module without constantly qualifying the object names with the name of their module.
Use include to copy a module's objects into the current namespace. You can then use them from the current namespace, without qualifying their names.
Instead of this:
	require 'rexml/document'



	REXML::Document.new(xml)
You might write this:
	require 'rexml/document'

	include REXML



	Document.new(xml)
This is the exact same include statement you use to incorporate a mixin module into a class you're writing. It does the same thing here as when it includes a mixin: it copies the contents of a module into the current namespace.
Here, though, the point isn't to add new functionality to a class or module: it's to save you from having to do so much typing. This technique is especially useful with large library modules like Curses and the Rails libraries.
This use of include comes with the same caveats as any other: if you already have variables with the same names as the objects being included, the included objects will be copied in over them and clobber them.
You can, of course, import a namespace that's nested within a namespace of its own. Instead of this:
	require 'rexml/parsers/pullparser'



	REXML::Parsers::PullParser.new("Some XML")
You might write this:
	require 'rexml/parsers/pullparser'

	include REXML::Parsers



	PullParser.new("Some XML")
  • Recipe 11.3, "Extracting Data While Parsing a Document"
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Initializing Instance Variables Defined by a Module
Inhaltsvorschau
Credit: Phil Tomson
You have a mixin module that defines some instance variables. Given a class that mixes in the module, you want to initialize the instance variables whenever an instance of the class is created.
Define an initialize method in the module, and call super in your class's constructor. Here's a Timeable module that tracks when objects are created and how old they are:
	module Timeable

	 attr_reader :time_created



	 def initialize

	   @time_created = Time.now

	 end



	 def age #in seconds

	   Time.now - @time_created

	 end

	end
Timeable has an instance variable time_created, and an initialize method that assigns Time.now (the current time) to the instance variable. Now let's mix Timeable into another class that also defines an initialize method:
	class Character

	  include Timeable

	  attr_reader :name

	  def initialize( name )

	    @name = name

	    super() #calls Timeable's initialize

	  end

	end

	c = Character.new "Fred"



	c.time_created

	# => Mon Mar 27 18:34:31 EST 2006
You can define and access instance variables within a module's instance methods, but you can't actually instantiate a module. A module's instance variables only exist within objects of a class that includes the module. However, classes don't usually need to know about the instance variables defined by the modules they include. That sort of information should be initialized and maintained by the module itself.
The Character#initialize method overrides the Timeable#initialize method, but you can use super to call the Timeable constructor from within the Character constructor. When a module is included in a class, that module becomes an ancestor of the class. We can test this in the context of the example above by calling the Module#ancestors on the Character class:
	Character.ancestors                    # => [Character, Timeable, Object, Kernel]
When you call super from within a method (such as initialize), Ruby finds every ancestor that defines a method with the same name, and calls it too.
  • Recipe 8.13, "Calling a Superclass's Method"
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Automatically Initializing Mixed-In Modules
Inhaltsvorschau
Credit: Phil Tomson
You've written a module that gets mixed into classes. Your module has some initialization code that needs to run whenever the mixed-into class is initialized. You do not want users of your module to have to call super in their initialize methods.
First, we need a way for classes to keep track of which modules they've included. We also need to redefine Class#new to call a module-level initialize method for each included module. Fortunately, Ruby's flexibility lets us makes changes to the built-in Class class (though this should never be done lightly):
	class Class

	  def included_modules

	    @included_modules ||= []

	  end



	  alias_method :old_new, :new

	  def new(*args, &block)

	    obj = old_new(*args, &block)

	    self.included_modules.each do |mod|

	      mod.initialize if mod.respond_to?(:initialize)

	    end

	    obj

	  end

	end
Now every class has a list of included modules, accessable from the included_modules class method. We've also redefined the Class#new method so that it iterates through all the modules in included_modules, and calls the module-level initialize method of each.
All that's missing is a way to add included modules to included_modules. We'll put this code into an Initializable module. A module that wants to be initializable can mix this module into itself and define an initialize method:
	module Initializable



	  def self.included(mod)

	    mod.extend ClassMethods

	  end



	  module ClassMethods

	    def included(mod)

	      if mod.class != Module #in case Initializeable is mixed-into a class 

	        puts "Adding #{self} to #{mod}'s included_modules" if $DEBUG 

	        mod.included_modules << self

	      end

	    end

	  end

	end
The included callback method is called whenever this module is included in another module. We're using the pattern shown in Recipe 9.3 to add an included callback method into the receiving module. If we didn't do this, you'd have to use that pattern yourself for every module you wanted to be Initializable.
That's a lot of code, but here's the payoff. Let's define a couple of modules which include
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Chapter 10: Reflection and Metaprogramming
Inhaltsvorschau
In a dynamic language like Ruby, few pieces are static. Classes can grow new methods and lose the ones they had before. Methods can be defined manually, or automatically with well-written code.
Probably the most interesting aspect of the Ruby programming philosophy is its use of reflection and metaprogramming to save the programmer from having to write repetitive code. In this chapter, we will teach you the ways and the joys of these techniques.
Reflection lets you treat classes and methods as objects. With reflection you can see which methods you can call on an object (Recipes 10.2 and 10.3). You can grab one of its methods as an object (Recipe 10.4), and call it or pass it in to another method as a code block. You can get references to the class an object implements and the modules it includes, and print out its inheritance structure (Recipe 10.1). Reflection is especially useful when you're interactively examining an unfamiliar object or class structure.
Metaprogramming is to programming as programming is to doing a task by hand. If you need to sort a file of a hundred lines, you don't open it up in a text editor and start shuffling the lines: you write a program to do the sort. By the same token, if you need to give a Ruby class a hundred similar methods, you shouldn't just start writing the methods one at a time. You should write Ruby code that defines the methods for you (Recipe 10.10). Or you should make your class capable of intercepting calls to those methods: this way, you can implement the methods without ever defining them at all (Recipe 10.8).
Methods you've seen already, like attr_reader, use metaprogramming to define custom methods according to your specifications. Recipe 8.2 created a few more of these "decorator" methods; Recipe 10.16 in this chapter shows a more complex example of the same principle.
You can metaprogram in Ruby either by writing normal Ruby code that uses a lot of reflection, or by generating a string that contains Ruby code, and evaluating the string. Writing normal Ruby code with reflection is generally safer, but sometimes the reflection just gets to be too much and you need to evaluate a string. We provide a demonstration recipe for each technique (Recipes 10.10 and 10.11).
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Finding an Object's Class and Superclass
Inhaltsvorschau
Given a class, you want an object corresponding to its class, or to the parent of its class.
Use the Object#class method to get the class of an object as a Class object. Use Class#superclass to get the parent Class of a Class object:
	'a string'.class                                   # => String

	'a string'.class.name                              # => "String"

	'a string'.class.superclass                        # => Object

	String.superclass                                  # => Object

	String.class                                       # => Class

	String.class.superclass                            # => Module

	'a string'.class.new                               # => ""
Class objects in Ruby are first-class objects that can be assigned to variables, passed as arguments to methods, and modified dynamically. Many of the recipes in this chapter and Chapter 8 discuss things you can do with a Class object once you have it.
The superclass of the Object class is nil. This makes it easy to iterate up an inheritance hierarchy:
	class Class

	  def hierarchy

	    (superclass ? superclass.hierarchy : []) << self

	  end

	end

	Array.hierarchy                                     # => [Object, Array]



	class MyArray < Array

	end

	MyArray.hierarchy                                   # => [Object, Array, MyArray]
While Ruby does not support multiple inheritance, the language allows mixin Modules that simulate it (see Recipe 9.1). The Modules included by a given Class (or another Module) are accessible from the Module#ancestors method.
A class can have only one superclass, but it may have any number of ancestors. The list returned by Module#ancestors contains the entire inheritance hierarchy (including the class itself), any modules the class includes, and the ever-present Kernel module, whose methods are accessible from anywhere because Object itself mixes it in.
	String.superclass                 # => Object

	String.ancestors                  # => [String, Enumerable, Comparable, Object, Kernel]

	Array.ancestors                   # => [Array, Enumerable, Object, Kernel]

	MyArray.ancestors                 # => [MyArray, Array, Enumerable, Object, Kernel]



	Object.ancestors                  # => [Object, Kernel]



	class MyClass

	end

	MyClass.ancestors                 # => [MyClass, Object, Kernel]
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Listing an Object's Methods
Inhaltsvorschau
Given an unfamiliar object, you want to see what methods are available to call.
All Ruby objects implement the Object#methods method. It returns an array containing the names of the object's public instance methods:
	Object.methods

	# => ["name", "private_class_method", "object_id", "new",

	# "singleton_methods", "method_defined?", "equal?", … ]
To get a list of the singleton methods of some object (usually, but not always, a class), use Object#singleton_methods:
	Object.singleton_methods    # => []

	Fixnum.singleton_methods    # => ["induced_from"]



	class MyClass

	  def MyClass.my_singleton_method

	  end



	  def my_instance_method

	  end

	end

	MyClass.singleton_methods    # => ["my_singleton_method"]
To list the instance methods of a class, call instance_methods on the object. This lets you list the instance methods of a class without instantiating the class:
	''.methods == String.instance_methods         # => true
The output of these methods are most useful when sorted:
	Object.methods.sort

	# => ["<", "<=", "<=>", "==", "===", "=~", ">", ">=",

	# "__id__", "__send__", "allocate", "ancestors", … ]
Ruby also defines some elementary predicates along the same lines. To see whether a class defines a certain instance method, call method_defined? on the class or respond_to? on an instance of the class. To see whether a class defines a certain class method, call respond_to? on the class:
	MyClass.method_defined? :my_instance_method     # => true

	MyClass.new.respond_to? :my_instance_method     # => true

	MyClass.respond_to? :my_instance_method         # => false



	MyClass.respond_to? :my_singleton_method        # => true
It often happens that while you're in an interactive Ruby session, you need to look up which methods an object supports, or what a particular method is called. Looking directly at the object is faster than looking its class up in a book. If you're using a library like Rails or Facets, or your code has been adding methods to the built-in classes, it's also more reliable.
Noninteractive code can also benefit from knowing whether a given object implements a certain method. You can use this to enforce an interface, allowing any object to be passed into a method so long as the argument implements certain methods (see Recipe 10.16).
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Listing Methods Unique to an Object
Inhaltsvorschau
When you list the methods available to an object, the list is cluttered with extraneous methods defined in the object's superclasses and mixed-in modules. You want to see a list of only the methods defined by that object's direct class.
Subtract the instance methods defined by the object's superclass. You'll be left with only the methods defined by the object's direct class (plus any methods defined on the object after its creation). The my_methods_only method defined below gives this capability to every Ruby object:
	class Object

	  def 

my_methods_only

	    my_super = self.class.superclass

	    return my_super ? methods - my_super.instance_methods : methods

	  end

	end



	s = ''

	s.methods.size                             # => 143

	Object.instance_methods.size               # =>  41

	s.my_methods_only.size                     # => 102

	(s.methods - Object.instance_methods).size # => 102



	def s.singleton_method( )

	end

	s.methods.size                             # => 144

	s.my_methods_only.size                     # => 103



	class Object

	  def new_object_method

	  end

	end

	s.methods.size                             # => 145

	s.my_methods_only.size                     # => 103



	class MyString < String

	  def my_string_method

	  end

	end

	MyString.new.my_methods_only               # => ["my_string_method"]
The my_methods_only technique removes methods defined in the superclass, the parent classes of the superclass, and in any mixin modules included by those classes. For instance, it removes the 40 methods defined by the Object class when it mixed in the Kernel module. It will not remove methods defined by mixin modules included by the class itself.
Usually these methods aren't clutter, but there can be a lot of them (for instance, Enumerable defines 22 methods). To remove them, you can start out with my_methods_only, then iterate over the ancestors of the class in question and subtract out all the methods defined in modules:
	class Object

	  def my_methods_only_no_mixins

	  self.class.ancestors.inject(methods) do |mlist, ancestor|

	    mlist = mlist - ancestor.instance_methods unless ancestor.is_a? Class

	    mlist

	  end

	end



	[].methods.size                                 # => 121

	[].my_methods_only.size                         # => 78

	[].my_methods_only_no_mixins.size               # => 57
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Getting a Reference to a Method
Inhaltsvorschau
You want to the name of a method into a reference to the method itself.
Use the eponymous Object#method method:
	s = 'A string'

	length_method = s.method(:length) # => #<Method: String#length>

	length_method.arity               # => 0

	length_method.call                # => 8
The Object#methods introspection method returns an array of strings, each containing the name of one of the methods available to that object. You can pass any of these names into an object's method method and get a Method object corresponding to that method of that object.
A Method object is bound to the particular object whose method method you called. Invoke the method's Method#call method, and it's just like calling the object's method directly:
	1.succ                            # => 2

	1.method(:succ).call              # => 2
The Method#arity method indicates how many arguments the method takes. Arguments, including block arguments, are passed to call just as they would be to the original method:
	5.method('+').call(10)            # => 15



	[1,2,3].method(:each).call { |x| puts x }

	# 1

	# 2

	# 3
A Method object can be stored in a variable and passed as an argument to other methods. This is useful for passing preexisting methods into callbacks and listeners:
	class EventSpawner



	  def initialize

	    @listeners = []

	    @state = 0

	  end



	  def subscribe(&listener)

	    @listeners << listener

	  end



	  def change_state(new_state)

	    @listeners.each { |l| l.call(@state, new_state) }

	    @state = new_state

	  end

	end



	class EventListener

	  def hear(old_state, new_state)

	    puts "Method triggered: state changed from #{old_state} " +

	      "to #{new_state}."

	  end

	end



	spawner = EventSpawner.new

	spawner.subscribe do |old_state, new_state|

	 puts "Block triggered: state changed from #{old_state} to #{new_state}."

	end



	spawner.subscribe &EventListener.new.method(:hear)

	spawner.change_state(4)

	# Block triggered: state changed from 0 to 4.

	# Method triggered: state changed from 0 to 4.
A Method can also be used as a block:
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Fixing Bugs in Someone Else's Class
Inhaltsvorschau
You're using a class that's got a bug in one of its methods. You know where the bug is and how to fix it, but you can't or don't want to change the source file itself.
Extend the class from within your program and overwrite the buggy method with an implementation that fixes the bug. Create an alias for the buggy version of the method, so you can still access it if necessary.
Suppose you're trying to use the buggy method in the Multiplier class defined below:
	class Multiplier

	  def double_your_pleasure(pleasure)

	    return pleasure * 3 # FIXME: Actually triples your pleasure.

	  end

	end



	m = Multiplier.new

	m.double_your_pleasure(6)                              # => 18
Reopen the class, alias the buggy method to another name, then redefine it with a correct implementation:
	class Multiplier

	  alias :double_your_pleasure_BUGGY :double_your_pleasure

	  def double_your_pleasure(pleasure)

	    return pleasure * 2

	  end

	end

	m.double_your_pleasure(6)                              # => 12



	m.double_your_pleasure_BUGGY(6)                        # => 18
In many programming languages a class, function, or method can't be modified after its initial definition. In other languages, this behavior is possible but not encouraged. For Ruby programmers, the ability to reprogram classes on the fly is just another technique for the toolbox, to be used when necessary. It's most commonly used to add new code to a class, but it can also be used to deploy a drop-in replacement for buggy or slow implementation of a method.
Since Ruby is (at least right now) a purely interpreted language, you should be able to find the source code of any Ruby class used by your program. If a method in one of those classes has a bug, you should be able to copy and paste the original Ruby implementation into your code and fix the bug in the new copy. This is not an elegant technique, but it's often better than distributing a slightly modified version of the entire class or library (that is, copying and pasting a whole file).
When you fix the buggy behavior, you should also send your fix to the maintainer of the software that contains the bug. The sooner you can get the fix out of your code, the better. If the software package is abandoned, you should at least post the fix online so others can find it.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Listening for Changes to a Class
Inhaltsvorschau
Credit: Phil Tomson
You want to be notified when the definition of a class changes. You might want to keep track of new methods added to the class, or existing methods that get removed or undefined. Being notified when a module is mixed into a class can also be useful.
Define the class methods method_added, method_removed, and/or method_undefined. Whenever the class gets a method added, removed, or undefined, Ruby will pass its symbol into the appropriate callback method.
The following example prints a message whenever a method is added, removed, or undefined. If the method "important" is removed, undefined, or redefined, it throws an exception.
	class Tracker

	  def important

	    "This is an important method!"

	  end



	  def self.method_added(sym)

	    if sym == :important

	      raise 'The "important" method has been redefined!'

	    else

	      puts %{Method "#{sym}" was (re)defined.}

	    end

	  end



	  def self.method_removed(sym)

	    if sym == :important

	      raise 'The "important" method has been removed!'

	    else

	      puts %{Method "#{sym}" was removed.}

	   end

	  end



	  def self.method_undefined(sym)

	    if sym == :important

	      raise 'The "important" method has been undefined!'

	    else

	      puts %{Method "#{sym}" was removed.}

	    end

	  end

	end
If someone adds a method to the class, a message will be printed:
	class Tracker

	  def new_method

	    'This is a new method.'

	  end

	end

	# Method "new_method" was (re)defined.
Short of freezing the class, you can't prevent the important method from being removed, undefined, or redefined, but you can raise a stink (more precisely, an exception) if someone changes it:
	class Tracker

	  undef :important

	end

	# RuntimeError: The "important" method has been undefined!
The class methods we've defined in the Tracker class (method_added, method_removed, and method_undefined) are hook methods. Some other piece of code (in this case, the Ruby interpreter) knows to call any methods by that name when certain conditions are met. The Module class defines these methods with empty bodies: by default, nothing special happens when a method is added, removed, or undefined.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Checking Whether an Object Has Necessary Attributes
Inhaltsvorschau
You're writing a class or module that delegates the creation of some of its instance variables to a hook method. You want to be make sure that the hook method actually created those instance variables.
Use the Object#instance_variables method to get a list of the instance variables. Check them over to make sure all the necessary instance variables have been defined. This Object#must_have_instance_variables method can be called at any time:
	class Object

	  def must_have_instance_variables(*args)

	    vars = instance_variables.inject({}) { |h,var| h[var] = true; h }

	    args.each do |var|

	      unless vars[var]

	        raise ArgumentError, %{Instance variable "@#{var} not defined"}

	      end

	    end

	  end

	end
The best place to call this method is in initialize or some other setup method of a module. Alternatively, you could accept values for the instance variables as arguments to the setup method:
	module LightEmitting

	  def LightEmitting_setup

	    must_have_instance_variables :light_color, :light_intensity

	    @on = false

	  end



	  # Methods that use @light_color and @light_intensity follow…

	end
You can call this method from a class that defines a virtual setup method, to make sure that subclasses actually use the setup method correctly:
	class Request

	  def initialize

	    gather_parameters # This is a virtual method defined by subclasses

	    must_have_instance_variables :action, :user, :authentication

	  end



	  # Methods that use @action, @user, and @authentication follow…

	end
Although Object#must_have_instance_variables is defined and called like any other method, it's conceptually a "decorator" method similar to attr_accessor and private. That's why I didn't use parentheses above, even though I called it with multiple arguments. The lack of parentheses acts as a visual indicator that you're calling a decorator method, one that alters or inspects a class or object.
Here's a similar method that you can use from outside the object. It basically implements a batch form of duck typing: instead of checking an object's instance variables (which are only available inside the object), it checks whether the object supports all of the methods you need to call on it. It's useful for checking from the outside whether an object is the "shape" you expect.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Responding to Calls to Undefined Methods
Inhaltsvorschau
Rather than having Ruby raise a NoMethodError when someone calls an undefined method on an instance of your class, you want to intercept the method call and do something else with it.
Or you are faced with having to explicitly define a large (possibly infinite) number of methods for a class. You would rather define a single method that can respond to an infinite number of method names.
Define a method_missing method for your class. Whenever anyone calls a method that would otherwise result in a NoMethodError, the method_missing method is called instead. It is passed the symbol of the nonexistent method, and any arguments that were passed in.
Here's a class that modifies the default error handling for a missing method:
	class MyClass

	  def defined_method

	    'This method is defined.'

	  end



	  def method_missing(m, *args)

	    "Sorry, I don't know about any #{m} method."

	  end

	end



	o = MyClass.new

	o.defined_method                      # => "This method is defined."

	o.undefined_method

	# => "Sorry, I don't know about any undefined_method method."
In the second example, I'll define an infinitude of new methods on Fixnum by giving it a method_missing implementation. Once I'm done, Fixnum will answer to any method that looks like "plus_#" and takes no arguments.
	class Fixnum

	  def method_missing(m, *args)

	    if args.size > 0

	      raise ArgumentError.new("wrong number of arguments (#{args.size} for 0)")

	    end

	    match = /^plus_([0-9]+)$/.match(m.to_s)

	    if match

	      self + match.captures[0].to_i

	    else

	      raise NoMethodError.

	    new(" 

undefined method '#{m}' for #{inspect}:#{self.class}")

	    end

	  end

	end



	4.plus_5                                         # => 9

	10.plus_0                                        # => 10

	-1.plus_2                                        # => 1

	100.plus_10000                                   # => 10100

	20.send(:plus_25)                                # => 45



	100.minus_3

	# NoMethodError:  

undefined method 'minus_3' for 100:Fixnum

	100.plus_5(105)

	# ArgumentError: wrong number of arguments (1 for 0)
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Automatically Initializing Instance Variables
Inhaltsvorschau
You're writing a class constructor that takes a lot of arguments, each of which is simply assigned to an instance variable.
	class RGBColor(red=0, green=0, blue=0)

	  @red = red

	  @green = green

	  @blue = blue

	end
You'd like to avoid all the typing necessary to do those variable assignments.
Here's a method that initializes the instance variables for you. It takes as an argument the list of variables passed into the initialize method, and the binding of the variables to values.
	class Object

	  private

	  def set_instance_variables(binding, *variables)

	    variables.each do |var|

	      instance_variable_set("@#{var}", eval(var, binding))

	    end

	  end

	end
Using this method, you can eliminate the tedious variable assignments:
	class RGBColor

	  def initialize(red=0, green=0, blue=0)

	    set_instance_variables(binding, *local_variables)

	  end

	end



	RGBColor.new(10, 200, 300)

	# => #<RGBColor:0xb7c22fc8 @red=10, @blue=300, @green=200>
Our set_ instance_variables takes a list of argument names to turn into instance variables, and a Binding containing the values of those arguments as of the method call. For each argument name, an eval statement binds the corresponding instance variable to the corresponding value in the Binding. Since you control the names of your own variables, this eval is about as safe as it gets.
The names of a method's arguments aren't accessible from Ruby code, so how do we get that list? Through trickery. When a method is called, any arguments passed in are immediately bound to local variables. At the very beginning of the method, these are the only local variables defined. This means that calling Kernel#local_variables at the beginning of a method will get a list of all the argument names.
If your method accepts arguments that you don't want to set as instance variables, simply remove their names from the result of Kernel#local_variables before passing the list into set_instance_variables:
	class RGBColor

	  def initialize(red=0, green=0, blue=0, debug=false)

	    set_instance_variables(binding, *local_variables-['debug'])

	    puts "Color: #{red}/#{green}/#{blue}" if debug

	  end

	end



	RGBColor.new(10, 200, 255, true)

	# Color: 10/200/255

	# => #<RGBColor:0xb7d309fc @blue=255, @green=200, @red=10>
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Avoiding Boilerplate Code with Metaprogramming
Inhaltsvorschau
You've got to type in a lot of repetitive code that a trained monkey could write. You're resentful at having to do this yourself, and angry that the repetitive code will clutter up your class listings.
Ruby is happy to be the trained monkey that writes your repetitive code. You can define methods algorithmically with Module#define_method.
Usually the repetitive code is a bunch of similar methods. Suppose you need to write code like this:
	class Fetcher

	  def fetch(how_many)

	    puts "Fetching #{how_many ? how_many : "all"}."

	  end

	  def fetch_one

	    fetch(1)

	  end



	  def fetch_ten

	   fetch(10)

	  end



	  def fetch_all

	    fetch(nil)

	  end

	end
You can define this exact same code without having to write it all out. Create a data structure that contains the differences between the methods, and iterate over that structure, defining a method each time with define_method.
	class GeneratedFetcher

	  def fetch(how_many)

	    puts "Fetching #{how_many ? how_many : "all"}."

	  end



	  [["one", 1], ["ten", 10], ["all", nil]].each do |name, number|

	    define_method("fetch_#{name}") do

	      fetch(number)

	    end

	  end

	end



	GeneratedFetcher.instance_methods - Object.instance_methods

	# => ["fetch_one", "fetch", "fetch_ten", "fetch_all"]



	GeneratedFetcher.new.fetch_one

	# Fetching 1.



	GeneratedFetcher.new.fetch_all

	# Fetching all.
This is less to type, less monkeyish, and it takes up less space in your class listing. If you need to define more of these methods, you can add to the data structure instead of writing out more boilerplate.
Programmers have always preferred writing new code to cranking out variations on old code. From lex and yacc to modern programs like Hibernate and Cog, we've always used tools to generate code that would be tedious to write out manually.
Instead of generating code with an external tool, Ruby programmers do it from within Ruby. There are two officially sanctioned techniques. The nicer technique is to use define_method to create a method whose implementation can use the local variables available at the time it was defined.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Metaprogramming with String Evaluations
Inhaltsvorschau
You're trying to write some metaprogramming code using define_method, but there's too much reflection going on for your code to be readable. It gets confusing and is almost as frustrating as having to write out the code in longhand.
You can define new methods by generating the definitions as strings and running them as Ruby code with one of the eval methods.
Here's a reprint of the metaprogramming example from the previous recipe, which uses define_method:
	class Numeric

	 [['add', '+'], ['subtract', '-'],

	  ['multiply', '*',], ['divide', '/']].each do |method, operator|

	    define_method("#{method}_2") do

	      method(operator).call(2)

	    end

	  end

	end
The important line of code, method(operator).call(2), isn't something you'd write in normal programming. You'd write something like self + 2 or self / 2, depending on which operator you wanted to apply. By writing your method definitions as strings, you can do metaprogramming that looks more like regular programming:
	class Numeric

	  [['add', '+'], ['subtract', '-'],

	   ['multiply', '*',], ['divide', '/']].each do |method, operator|

	    module_eval %{ def #{method}_2

	                     self.#{operator}(2)

	                   end }

	  end

	end



	4.add_2                                                  # => 6

	10.divide_2                                              # => 5
You can do all of your metaprogramming with define_method, but the code doesn't look a lot like the code you'd write in normal programming. You can't set an instance variable with @foo=4; you have to call instance_variable_set('foo', 4).
The alternative is to generate a method definition as a string and execute the string as Ruby code. Most interpreted languages have a way of parsing and executing arbitrary strings as code, but it's usually regarded as a toy or a hazard, and not given much attention. Ruby breaks this taboo.
The most common evalutation method used for metaprogramming is Module#module_eval. This method executes a string as Ruby code, within the context of a class or module. Any methods or class variables you define within the string will be attached to the class or module, just as if you'd typed the string within the class or module definition. Thanks to the variable substitutions, the generated string looks exactly like the code you'd type in manually.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Evaluating Code in an Earlier Context
Inhaltsvorschau
You've written a method that evaluates a string as Ruby code. But whenever anyone calls the method, the objects referenced by your string go out of scope. Your string can't be evaluated within a method.
For instance, here's a method that takes a variable name and tries to print out the value of the variable.
	def broken_print_variable(var_name)

	  eval %{puts "The value of #{var_name} is " + #{var_name}.to_s}

	end
The eval code only works when it's run in the same context as the variable definition. It doesn't work as a method, because your local variables go out of scope when you call a method.
	tin_snips = 5



	broken_print_variable('tin_snips')

	# NameError: undefined local variable or method 'tin_snips' for main:Object



	var_name = 'tin_snips'

	eval %{puts "The value of #{var_name} is " + #{var_name}.to_s}

	# The value of tin_snips is 5
The eval method can execute a string of Ruby code as though you had written in some other part of your application. This magic is made possible by Binding objects. You can get a Binding at any time by calling Kernel#binding, and pass it in to eval to recreate your original environment where it wouldn't otherwise be available. Here's a version of the above method that takes a Binding:
	def print_variable(var_name, binding)

	  eval %{puts "The value of #{var_name} is " + #{var_name}.to_s}, binding

	end



	vice_grips = 10

	print_variable('vice_grips', binding)

	# The value of vice_grips is 10
A Binding object is a bookmark of the Ruby interpreter's state. It tracks the values of any local variables you have defined, whether you are inside a class or method definition, and so on.
Once you have a Binding object, you can pass it into eval to run code in the same context as when you created the Binding. All the local variables you had back then will be available. If you called Kernel#binding within a class definition, you'll also be able to define new methods of that class, and set class and instance variables.
Since a Binding object contains references to all the objects that were in scope when it was created, those objects can't be garbage-collected until both they and the
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Undefining a Method
Inhaltsvorschau
You want to remove an already defined method from a class or module.
From within a class or module, you can use Module#remove_method to remove a method's implementation, forcing Ruby to delegate to the superclass or a module included by a class.
In the code below, I subclass Array and override the << and [] methods to add some randomness. Then I decide that overriding [] wasn't such a good idea, so I undefine that method and get the inherited Array behavior back. The override of << stays in place.
	class RandomizingArray < Array

	  def <<(e)

	    insert(rand(size), e)

	  end



	  def [](i)

	    super(rand(size))

	  end

	end



	a = RandomizingArray.new

	a << 1 << 2 << 3 << 4 << 5 << 6  # => [6, 3, 4, 5, 2, 1]



	# That was fun; now let's get some of those entries back.

	a[0]                                                                 # => 1

	a[0]                                                                 # => 2

	a[0]                                                                 # => 5

	#No, seriously, a[0].

	a[0]                                                                 # => 4

	#It's a madhouse! A madhouse!

	a[0]                                                                 # => 3

	#That does it!



	class RandomizingArray

	  remove_method('[]')

	end



	a[0]                                                                 # => 6

	a[0]                                                                 # => 6

	a[0]                                                                 # => 6



	# But the overridden << operator still works randomly:

	a << 7                                                         # => [6, 3, 4, 7, 5, 2, 1]
Usually you'll override a method by redefining it to implement your own desired behavior. However, sometimes a class will override an inherited method to do something you don't like, and you just want the "old" implementation back.
You can only use remove_method to remove a method from a class or module that explicitly defines it. You'll get an error if you try to remove a method from a class that merely inherits that method. To make a subclass stop responding to an inherited method, you should
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Aliasing Methods
Inhaltsvorschau
You (or your users) frequently misremember the name of a method. To reduce the confusion, you want to make the same method accessible under multiple names.
Alternatively, you're about to redefine a method and you'd like to keep the old version available.
You can create alias methods manually, but in most cases, you should let the alias command do it for you. In this example, I define an InventoryItem class that includes a price method to calculate the price of an item in quantity. Since it's likely that someone might misremember the name of the price method as cost, I'll create an alias:
	class InventoryItem

	  attr_accessor :name, :unit_price



	  def initialize(name, unit_price)

	    @name, @unit_price = name, unit_price

	  end



	  def price(quantity=1)

	    @unit_price * quantity

	  end



	  #Make InventoryItem#cost an alias for InventoryItem#price

	  alias :cost :price

	

	  #The attr_accessor decorator created two methods called "unit_price" and

	  #"unit_price=". I'll create 

aliases for those methods as well.

	  alias :unit_cost :unit_price

	  alias :unit_cost= :unit_price=

	end



	bacon = InventoryItem.new("Chunky Bacon", 3.95)

	bacon.price(100)                                  # => 395.0

	bacon.cost(100)                                   # => 395.0



	bacon.unit_price                                  # => 3.95

	bacon.unit_cost                                   # => 3.95

	bacon.unit_cost = 3.99

	bacon.cost(100)                                   # => 399.0
It's difficult to pick the perfect name for a method: you must find the word or short phrase that best conveys an operation on a data structure, possibly an abstract operation that has different "meanings" depending on context.
Sometimes there will be no good name for a method and you'll just have to pick one; sometimes there will be too many good names for a method and you'll just have to pick one. In either case, your users may have difficulty remembering the "right" name of the method. You can help them out by creating aliases.
Ruby itself uses aliases in its standard library: for instance, for the method of
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Doing Aspect-Oriented Programming
Inhaltsvorschau
You want to "wrap" a method with new code, so that calling the method triggers some new feature in addition to the original code.
You can arrange for code to be called before and after a method invocation by using method aliasing and metaprogramming, but it's simpler to use the glue gem or the AspectR third-party library. The latter lets you define "aspect" classes whose methods are called before and after other methods.
Here's a simple example that traces calls to specific methods as they're made:
	require 'aspectr'

	class Verbose < AspectR::Aspect



	 def describe(method_sym, object, *args)

	    "#{object.inspect}.#{method_sym}(#{args.join(",")})"

	  end



	  def before(method_sym, object, return_value, *args)

	    puts "About to call #{describe(method_sym, object, *args)}."

	  end



	  def after(method_sym, object, return_value, *args)

	    puts "#{describe(method_sym, object, *args)} has returned " +

	      return_value.inspect + '.'

	  end

	end
Here, I'll wrap the push and pop methods of an array. Every time I call those methods, the aspect code will run and some diagnostics will be printed.
	verbose = Verbose.new

	stack = []

	verbose.wrap(stack, :before, :after, :push, :pop)



	stack.push(10)

	# About to call [].push(10).

	# [10].push(10) has returned [[10]].



	stack.push(4)

	# About to call [10].push(4).

	# [10, 4].push(4) has returned [[10, 4]].



	stack.pop

	# About to call [10, 4].pop().

	# [10].pop() has returned [4].
There's a pattern that shows up again and again in Ruby (we cover it in Recipe 7.10). You write a method that performs some task-specific setup (like initializing a timer), runs a code block, then performs task-specific cleanup (like stopping the timer and printing out timing results). By passing in a code block to one of these methods you give it a new aspect: the same code runs as if you'd just called Proc#call on the code block, but now it's got something extra: the code gets timed, or logged, or won't run without authentication, or it automatically performs some locking.
Aspect-oriented programming lets you permanently add these aspects to previously defined methods, without having to change any of the code that calls them. It's a good way to modularize your code, and to modify existing code without having to do a lot of metaprogramming yourself. Though less mature, the AspectR library has the same basic features of Java's AspectJ.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Enforcing Software Contracts
Inhaltsvorschau
Credit: Maurice Codik
You want your methods to to validate their arguments, using techniques like duck typing and range validation, without filling your code with tons of conditions to test arguments.
Here's a Contracts module that you can mix in to your classes. Your methods can then define and enforce contracts.
	module Contracts

	  def valid_contract(input)

	    if @user_defined and @user_defined[input]

	      @user_defined[input]

	    else

	      case input

	      when :number

	        lambda { |x| x.is_a? Numeric }

	      when :string

	        lambda { |x| x.respond_to? :to_str }

	      when :anything

	        lambda { |x| true }

	      else

	        lambda { |x| false }

	      end

	    end

	  end



	  class ContractViolation < StandardError

	  end



	  def define_data(inputs={}.freeze)

	    @user_defined ||= {}

	    inputs.each do |name, contract|

	      @user_defined[name] = contract if contract.respond_to? :call

	    end

	  end



	  def contract(method, *inputs)

	    @contracts ||= {}

	    @contracts[method] = inputs

	    method_added(method)

	  end



	  def setup_contract(method, inputs)

	    @contracts[method] = nil

	    method_renamed = "__#{method}".intern

	    conditions = ""

	    inputs.flatten.each_with_index do |input, i|

	      conditions << %{

	       if not self.class.valid_contract(#{input.inspect}).call(args[#{i}])

	          raise ContractViolation, "argument #{i+1} of method '#{method}' must" +

	                  "satisfy the '#{input}' contract", caller

	        end

	      }

	    end



	   class_eval %{

	       alias_method #{method_renamed.inspect}, #{method.inspect}

	       def #{method}(*args)

	         #{conditions}

	         return #{method_renamed}(*args)

	       end

	     }

	  end



	  def method_added(method)

	    inputs = @ 

contracts[method]

	    setup_contract(method, inputs) if inputs

	  end

	end
You can call the define_data method to define contracts, and call the contract method to apply these contracts to your methods. Here's an example:
	class TestContracts

	  def hello(n, s, f)

	    n.times { f.write "hello #{s}!\n" }

	  end
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Chapter 11: XML and HTML
Inhaltsvorschau
XML and HTML are the most popular markup languages (textual ways of describing structured data). HTML is used to describe textual documents, like you see on the Web. XML is used for just about everything else: data storage, messaging, configuration files, you name it. Just about every software buzzword forged over the past few years involves XML.
Java and C++ programmers tend to regard XML as a lightweight, agile technology, and are happy to use it all over the place. XML is a lightweight technology, but only compared to Java or C++. Ruby programmers see XML from the other end of the spectrum, and from there it looks pretty heavy. Simpler formats like YAML and JSON usually work just as well (see Recipe 13.1 or Recipe 13.2), and are easier to manipulate. But to shun XML altogether would be to cut Ruby off from the rest of the world, and nobody wants that. This chapter covers the most useful ways of parsing, manipulating, slicing, and dicing XML and HTML documents.
There are two standard APIs for manipulating XML: DOM and SAX. Both are overkill for most everyday uses, and neither is a good fit for Ruby's code-block–heavy style. Ruby's solution is to offer a pair of APIs that capture the style of DOM and SAX while staying true to the Ruby programming philosophy. Both APIs are in the standard library's REXML package, written by Sean Russell.
Like DOM, the Document class parses an XML document into a nested tree of objects. You can navigate the tree with Ruby accessors (Recipe 11.2)or with XPath queries (Recipe 11.4). You can modify the tree by creating your own Element and Text objects (Recipe 11.9). If even Document is too heavyweight for you, you can use the XmlSimple library to transform an XML file into a nested Ruby hash (Recipe 11.6).
With a DOM-style API like Document, you have to parse the entire XML file before you can do anything. The XML document becomes a large number of Ruby objects nested under a Document object, all sitting around taking up memory. With a SAXstyle parser like the StreamParser class, you can process a document as it's parsed, creating only the objects you want. The
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Checking XML Well-Formedness
Inhaltsvorschau
Credit: Rod Gaither
You want to check that an XML document is well-formed before processing it.
The best way to see whether a document is well-formed is to try to parse it. The REXML library raises an exception when it can't parse an XML document, so just try parsing it and rescue any exception.
The valid_xml? method below returns nil unless it's given a valid XML document. If the document is valid, it returns a parsed Document object, so you don't have to parse it again:
	require 'rexml/document'

	def 

valid_xml?(xml)

	 begin

	   REXML::Document.new(xml)

	 rescue REXML::ParseException

	   # Return nil if an exception is thrown

	 end

	end
To be useful, an XML document must be structured correctly or "well-formed." For instance, an opening tag must either be self-closing or be paired with an appropriate closing tag.
As a file and messaging format, XML is often used in situations where you don't have control over the input, so you can't assume that it will always be well-formed. Rather than just letting REXML throw an exception, you'll need to handle ill-formed XML gracefully, providing options to retry or continue on a different path.
This bit of XML is not well-formed: it's missing ending tags for both the pending and done elements:
	bad_xml = %{

	<tasks>

	 <pending>

	   <entry>Grocery Shopping</entry>

	 <done>

	   <entry>Dry Cleaning</entry>

	</tasks>}



	valid_xml?(bad_xml)                           # => nil
This bit of XML is well-formed, so valid_xml? returns the parsed Document object.
	good_xml = %{

	<groceries>

	 <bread>Wheat</bread>

	 <bread>Quadrotriticale</bread>

	</groceries>}



	doc = valid_xml?(good_xml)

	doc.root.elements[1]                          # => <bread> … </>
When your program is responsible for writing XML documents, you'll want to write unit tests that make sure you generate valid XML. You can use a feature of the Test:: Unit library to simplify the checking. Since invalid XML makes REXML throw an exception, your unit test can use the assert_nothing_thrown method to make sure your XML is valid:
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Extracting Data from a Document's Tree Structure
Inhaltsvorschau
Credit: Rod Gaither
You want to parse an XML file into a Ruby data structure, to traverse it or extract data from it.
Pass an XML document into the REXML::Document constructor to load and parse the XML. A Document object contains a tree of subobjects (of class Element and Text) rep-resenting the tree structure of the underlying document. The methods of Document and Element give you access to the XML tree data. The most useful of these methods is #each_element.
Here's some sample XML and the load process. The document describes a set of orders, each of which contains a set of items. This particular document contains a single order for two items.
	orders_xml = %{

	<orders>

	  <order>

	    <number>105</number>

	    <date>02/10/2006</date>

	    <customer>Corner Store</customer>

	    <items>

	      <item upc="404100" desc="Red Roses" qty="240" />

	      <item upc="412002" desc="Candy Hearts" qty="160" />

	    </items>

	  </order>

	</orders>}



	require 'rexml/document'

	orders = REXML::Document.new(orders_xml)
To process each order in this document, we can use Document#root to get the document's root element (<orders>)and then call Element#each_element to iterate over the children of the root element (the <order> elements). This code repeatedly calls each to move down the document tree and print the details of each order in the document:
	orders.root.each_element do |order|    # each <order> in <orders>

	  order.each_element do |node|         # <customer>, <items>, etc. in <order>

	    if node.has_elements?

	      node.each_element do |child|     # each <item> in <items>

	        puts "#{child.name}: #{child.attributes['desc']}"

	      end

	    else

	      # the contents of <number>, <date>, etc.

	      puts "#{node.name}: #{node.text}"

	    end

	  end

	end

	# number: 105

	# date: 02/10/2006

	# customer: Corner Store

	# item: Red Roses

	# item: Candy Hearts
Parsing an XML file into a Document gives you a tree-like data structure that you can treat kind of like an array of arrays. Starting at the document root, you can move down the tree until you find the data that interests you. In the example above, note how the structure of the Ruby code mirrors the structure of the original document. Every call to
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Extracting Data While Parsing a Document
Inhaltsvorschau
Credit: Rod Gaither
You want to process a large XML file without loading it all into memory.
The method REXML::Document.parse_stream gives you a fast and flexible way to scan a large XML file and process the parts that interest you.
Consider this XML document, the output of a hypothetical program that runs auto mated tasks. We want to parse the document and find the tasks that failed (that is, returned an error code other than zero).
	event_xml = %{

	<events>

	  <clean system="dev" start="01:35" end="01:55" area="build" error="1" />

	  <backup system="prod" start="02:00" end="02:35" size="2300134" error="0" />

	  <backup system="dev" start="02:00" end="02:01" size="0" error="2" />

	  <backup system="test" start="02:00" end="02:47" size="327450" error="0" />

	</events>}
We can process the document as it's being parsed by writing a REXML:: StreamListener subclass that responds to parsing events such as tag_start and tag_end. Here's a subclass that listens for tags with a nonzero value for their error attribute. It prints a message for every failed event it finds.
	require 'rexml/document'

	require 'rexml/streamlistener'



	class ErrorListener

	  include REXML::StreamListener

	  def tag_start(name, attrs)

	    if attrs["error"] != nil and attrs["error"] != "0"

	      puts %{Event "#{name}" failed for system "#{attrs["system"]}" } +

	    %{with code #{attrs["error"]}}

	    end

	  end

	end
To actually parse the XML data, pass it along with the StreamListener into the method REXML::Document.parse_stream:
	REXML::Document.parse_stream(event_xml, ErrorListener.new)

	# Event "clean" failed for system "dev" with code 1

	# Event "backup" failed for system "dev" with code 2
We could find the failed events in less code by loading the XML into a Document and running an XPath query. That approach would work fine for this example, since the document only contains four events. It wouldn't work as well if the document were a file on disk containing a billion events. Building a Document means building an elaborate in-memory data structure representing the entire XML document. If you only care about part of a document (in this case, the failed events), it's faster and less memory-intensive to process the document as it's being parsed. Once the parser reaches the end of the document, you're done.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Navigating a Document with XPath
Inhaltsvorschau
You want to find or address sections of an XML document in a standard, programming-language–independent way.
The XPath language defines a way of referring to almost any element or set of elements in an XML document, and the REXML library comes with a complete XPath implementation. REXML::XPath provides three class methods for locating Element objects within parsed documents: first, each, and match.
Take as an example the following XML description of an aquarium. The aquarium contains some fish and a gaudy castle decoration full of algae. Due to an aquarium stocking mishap, some of the smaller fish have been eaten by larger fish, just like in those cartoon food chain diagrams. (Figure 11-1 shows the aquarium.)
	xml = %{

	<aquarium>

	 <fish color="blue" size="small" />



	 <fish color="orange" size="large">

	   <fish color="green" size="small">

	    <fish color="red" size="tiny" />

	   </fish>

	 </fish>



	 <decoration type="castle" style="gaudy">

	   <algae color="green" />

	  </decoration>

	 </aquarium>}



	 require 'rexml/document'

	 doc = REXML::Document.new xml
Figure 11-1: The aquarium
We can use REXML:: Xpath.first to get the Element object corresponding to the first <fish> tag in the document:
	REXML::XPath.first(doc, '//fish')

	# => <fish size='small' color='blue'/>
We can use match to get an array containing all the elements that are green:
	REXML::XPath.match(doc, '//[@color="green"]')

	# => [<fish size='small' color='green'> … </>, <algae color='green'/>]
We can use each with a code block to iterate over all the fish that are inside other fish:
	def describe(fish)

	  "#{fish.attribute('size')} #{fish.attribute('color')} fish"

	end

	REXML:: 

XPath.each(doc, '//fish/fish') do |fish|

	  puts "The #{describe(fish.parent)} has eaten the #{describe(fish)}."

	end

	# The large orange fish has eaten the small green fish.

	# The small green fish has eaten the tiny red fish.
Every element in a Document has an xpath method that returns the canonical XPath path to that element. This path can be considered the element's "address" within the document. In this example, a complex bit of Ruby code is replaced by a simple XPath expression:
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Parsing Invalid Markup
Inhaltsvorschau
You need to extract data from a document that's supposed to be HTML or XML, but that contains some invalid markup.
For a quick solution, use Rubyful Soup, written by Leonard Richardson and found in the rubyful_soup gem. It can build a document model even out of invalid XML or HTML, and it offers an idiomatic Ruby interface for searching the document model. It's good for quick screen-scraping tasks or HTML cleanup.
	require 'rubygems'

	require 'rubyful_soup'



	invalid_html = 'A lot of <b class=1>tags are <i class=2>never closed.'

	soup = BeautifulSoup.new(invalid_html)

	puts soup.prettify

	# A lot of

	#  <b class="1">tags are

	#   <i class="2">never closed.

	#   </i>

	#  </b>



	soup.b.i                                       # => <i class="2">never closed.</i>

	soup.i                                         # => <i class="2">never closed.</i>

	soup.find(nil, :attrs=>{'class' => '2'}) # => <i class="2">never closed.</i>

	soup.find_all('i')                             # => [<i class="2">never closed.</i>]



	soup.b['class']                                # => "1"



	soup.find_text(/closed/)                       # => "never closed."
If you need better performance, do what Rubyful Soup does and write a custom parser on top of the event-based parser SGMLParser (found in the htmltools gem). It works a lot like REXML's StreamListener interface.
Sometimes it seems like the authors of markup parsers do their coding atop an ivory tower. Most parsers simply refuse to parse bad markup, but this cuts off an enormous source of interesting data. Most of the pages on the World Wide Web are invalid HTML, so if your application uses other peoples' web pages as input, you need a forgiving parser. Invalid XML is less common but by no means rare.
The SGMLParser class in the htmltools gem uses regular expressions to parse an XMLlike data stream. When it finds an opening or closing tag, some data, or some other part of an XML-like document, it calls a hook method that you're supposed to define in a subclass. SGMLParser
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Converting an XML Document into a Hash
Inhaltsvorschau
When you parse an XML document with Document.new, you get a representation of the document as a complex data structure. You'd like to represent an XML document using simple, built-in Ruby data structures.
Use the XmlSimple library, found in the xml-simple gem. It parses an XML document into a hash.
Consider an XML document like this one:
	xml = %{

	<freezer temp="-12" scale="celcius">

	 <food>Phyllo dough</food>

	 <food>Ice cream</food>

	 <icecubetray>

	  <cube1 />

	  <cube2 />

	 </icecubetray>

	</freezer>}
Here's how you parse it with XMLSimple:
	require 'rubygems'

	require 'xmlsimple'



	doc = XmlSimple.xml_in xml
And here's what it looks like:
	require 'pp'

	pp doc

	# {"icecubetray"=>[{"cube2"=>[{}], "cube1"=>[{}]}],

	#  "food"=>["Phyllo dough", "Ice cream"],

	#  "scale"=>"celcius",

	#  "temp"=>"-12"}
XmlSimple is a lightweight alternative to the Document class. Instead of exposing a tree of Element objects, it exposes a nested structure of Ruby hashes and arrays. There's no performance savings (XmlSimple actually builds a Document class behind the scenes and iterates over it, so it's about half as fast as Document), but the resulting object is easy to use. XmlSimple also provides several tricks that can make a document more concise and navigable.
The most useful trick is the KeyAttr one. Suppose you had a better-organized freezer than the one above, a freezer in which everything had its own name attribute:
	xml = %{

	<freezer temp="-12" scale="celcius">

	 <item name="Phyllo dough" type="food" />

	 <item name="Ice cream" type="food" />

	 <item name="Ice cube tray" type="container">

	  <item name="Ice cube" type="food" />

	  <item name="Ice cube" type="food" />

	 </item>

	</freezer>}
You could parse this data with just a call to XmlSimple.xml_in, but you get a more concise representation by specifing the name attribute as a KeyAttr argument. Compare:
	parsed1 = XmlSimple.xml_in xml

	pp parsed1

	# {"scale"=>"celcius",

	#  "item"=>

	#   [{"name"=>"Phyllo dough", "type"=>"food"},

	#    {"name"=>"Ice cream", "type"=>"food"},

	# {"name"=>"Ice cube tray",

	#    "type"=>"container",

	#    "item"=>

	#    [
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Validating an XML Document
Inhaltsvorschau
Credit: Mauro Cicio
You want to check whether an XML document conforms to a certain schema or DTD.
Unfortunately, as of this writing there are no stable, pure Ruby libraries that do XML validation. You'll need to install a Ruby binding to a C library. The easiest one to use is the Ruby binding to the GNOME libxml2 toolkit. (There are actually two Ruby bindings to libxml2, so don't get confused: we're referring to the one you get when you install the libxml-ruby gem.)
To validate a document against a DTD, create a a DTD object and pass it into Document#validate. To validate against an XML Schema, pass in a Schema object instead.
Consider the following DTD, for a cookbook like this one:
	require 'rubygems'

	require ' 

libxml'



	dtd = XML::Dtd.new(%{<!ELEMENT rubycookbook (recipe+)>

	<!ELEMENT recipe (title?, problem, solution, discussion, seealso?)+>

	<!ELEMENT title (#PCDATA)>

	<!ELEMENT problem (#PCDATA)>

	<!ELEMENT solution (#PCDATA)>

	<!ELEMENT discussion (#PCDATA)>

	<!ELEMENT seealso (#PCDATA)>})
Here's an XML document that looks like it conforms to the DTD:
	open('cookbook.xml', 'w') do |f|

	  f.write %{<?xml version="1.0"?>

	<rubycookbook>

	 <recipe>

	   <title>A recipe</title>

	   <problem>A difficult/common problem</problem>

	   <solution>A smart solution</solution>

	   <discussion>A deep solution</discussion>

	   <seealso>Pointers</seealso>

	 </recipe>

	</rubycookbook>

	}

	end
But does it really? We can tell for sure with Document#validate:
	document = XML::Document.file('cookbook.xml')

	document.validate(dtd)                           # => true
Here's a Schema definition for the same document. We can validate the document against the schema by making it into a Schema object and passing that into Document#validate:
	schema = XML::Schema.from_string %{<?xml version="1.0"?>



	<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">

	  <xsd:element name="recipe" type="recipeType"/>



	  <xsd:element name="rubycookbook" type="rubycookbookType"/>

	  

	  <xsd:element name="title"      type="xsd:string"/>

	  <xsd:element name="problem"    type="xsd:string"/>

	  <xsd:element name="solution"   type="xsd:string"/>

	  <xsd:element name="discussion" type="xsd:string"/>

	  <xsd:element name="seealso"    type="xsd:string"/>



	  <xsd:complexType name="rubycookbookType">

	   <xsd:sequence>

	      <xsd:element ref="recipe"/>

	    </xsd:sequence>

	 </xsd:complexType>

	  <xsd:complexType name="recipeType">

	    <xsd:sequence>

	      <xsd:element ref="title"/>

	      <xsd:element ref="problem"/>

	      <xsd:element ref="solution"/>

	      <xsd:element ref="discussion"/>

	      <xsd:element ref="seealso"/>

	  </xsd:sequence>

	</xsd:complexType>



	</xsd:schema>

	}



	document.validate(schema)                         	# => true
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Substituting XML Entities
Inhaltsvorschau
You've parsed a document that contains internal XML entities. You want to substitute the entities in the document for their values.
To perform entity substitution on a specific text element, call its value method. If it's the first text element of its parent, you can call text on the parent instead.
Here's a simple document that defines and uses two entities in a single text node. We can substitute those entities for their values without changing the document itself:
	require 'rexml/document'



	str = %{<?xml version="1.0"?>

	<!DOCTYPE doc [

	  <!ENTITY product 'Stargaze'>

	  <!ENTITY version '2.3'>

	]>

	<doc>

	 &product; v&version; is the most advanced astronomy product on the market.

	</doc>}

	doc = REXML::Document.new str



	doc.root.children[0].value

	# => "\n Stargaze v2.3 is the most advanced astronomy product on the market.\n"

	doc.root.text

	# => "\n Stargaze v2.3 is the most advanced astronomy product on the market.\n"



	doc.root.children[0].to_s

	# => "\n &product; v&version; is the most advanced astronomy product on the market.\n"

	doc.root.write

	# <doc>

	# &product; v&version; is the most advanced astronomy program on the market.

	# </doc>
Internal XML entities are often used to factor out data that changes a lot, like dates or version numbers. But REXML only provides a convenient way to perform substitution on a single text node. What if you want to perform substitutions throughout the entire document?
When you call Document#write to send a document to some IO object, it ends up calling Text#to_s on each text node. As seen in the Solution, this method presents a "normalized" view of the data, one where entities are displayed instead of having their values substituted in.
We could write our own version of Document#write that presents an "unnormalized" view of the document, one with entity values substituted in, but that would be a lot of work. We could hack Text#to_s to work more like Text#value, or hack Text#write to call the value method instead of to_s. But it's less intrusive to do the entity replacement outside of the write method altogether. Here's a class that wraps any
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Creating and Modifying XML Documents
Inhaltsvorschau
You want to modify an XML document, or create a new one from scratch.
To create an XML document from scratch, just start with an empty Document object.
	require 'rexml/document'

	require

	doc = REXML::Document.new
To add a new element to an existing document, pass its name and any attributes into its parent's add_element method. You don't have to create the Element objects yourself.
	meeting = doc.add_element 'meeting'

	meeting_start = Time.local(2006, 10, 31, 13)

	meeting.add_element('time', { 'from' => meeting_start,

	                              'to' => meeting_start + 3600 })



	doc.children[0]                                 # => <meeting> … </>

	doc.children[0].children[0]

	# => "<time from='Tue Oct 31 13:00:00 EST 2006'

	#      to='Tue Oct 31 14:00:00 EST 2006'/>"



	doc.write($stdout, 1)

	# <meeting>

	#  <time from='Tue Oct 31 13:00:00 EST 2006'

	#        to='Tue Oct 31 14:00:00 EST 2006'/>

	# </meeting>

	doc.children[0]                                 # => <?xml … ?>

	doc.children[1]                                 # => <meeting> … </>
To append a text node to the contents of an element, use the add_text method. This code adds an <agenda> element to the <meeting> element, and gives it two different text nodes:
	agenda = meeting.add_element 'agenda'

	doc.children[1].children[1]               # => <agenda/>



	agenda. 

add_text "Nothing of importance will be decided."

	agenda.add_text " The same tired ideas will be rehashed yet again."



	doc.children[1].children[1]               # => <agenda> … </>



	doc.write($stdout, 1)

	# <meeting>

	#  <time from='Tue Oct 31 13:00:00 EST 2006'

	#         to='Tue Oct 31 14:00:00 EST 2006'/>

	#  <agenda>

	#   Nothing of importance will be decided. The same tired ideas will be

	#   rehashed yet again.

	#  </agenda>

	# </meeting>
Element#text= is a nice shortcut for giving an element a single text node. You can also use to overwrite a document's initial text nodes:
	item1 = agenda.add_element 'item'

	doc.children[1].children[1].children[1]       # => <item/>

	item1.text = 'Weekly status meetings: improving attendance'

	doc.children[1].children[1].children[1]       # => <item> … </>

	doc.write($stdout, 1)

	# <meeting>

	#  <time from='Tue Oct 31 13:00:00 EST 2006'

	#        to='Tue Oct 31 14:00:00 EST 2006'/>

	#  <agenda>

	#   Nothing of importance will be decided. The same tired ideas will be

	#   rehashed yet again.

	#   <item>Weekly status meetings: improving attendance</item>

	#  </agenda>

	# </meeting>
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Compressing Whitespace in an XML Document
Inhaltsvorschau
When REXML parses a document, it respects the original whitespace of the document's text nodes. You want to make the document smaller by compressing extra whitespace.
Parse the document by creating a REXML::Document out of it. Within the Document constructor, tell the parser to compress all runs of whitespace characters:
	require 'rexml/document'



	text = %{<doc><a>Some whitespace</a> <b>Some more</b></doc>}



	REXML::Document.new(text, { :compress_whitespace => :all }).to_s

	# => "<doc><a>Some whitespace</a> <b>Some more</b></doc>"
Sometimes whitespace within a document is significant, but usually (as with HTML) it can be compressed without changing the meaning of the document. The resulting document takes up less space on the disk and requires less bandwidth to transmit.
Whitespace compression doesn't have to be all-or-nothing. REXML gives two ways to configure it. Instead of passing :all as a value for :compress_whitespace, you can pass in a list of tag names. Whitespace will only be compressed in those tags:
	REXML::Document.new(text, { :compress_whitespace => %w{a} }).to_s

	# => "<doc><a>Some whitespace</a> <b>Some more</b></doc>"
You can also switch it around: pass in :respect_whitespace and a list of tag names whose whitespace you don't want to be compressed. This is useful if you know that whitespace is significant within certain parts of your document.
	REXML::Document.new(text, { :respect_whitespace => %w{a} }).to_s

	# => "<doc><a>Some whitespace</a> <b>Some more</b></doc>"
What about text nodes containing only whitespace? These are often inserted by XML pretty-printers, and they can usually be totally discarded without altering the meaning of a document. If you add :ignore_whitespace_nodes => :all to the parser configuration, REXML will simply decline to create text nodes that contain nothing but whitespace characters. Here's a comparison of :compress_whitespace alone, and in conjunction with :ignore_whitespace_nodes:
	text = %{<doc><a>Some text</a>\n <b>Some more</b>\n\n}

	REXML::Document.new(text, { :compress_whitespace => :all }).to_s

	# => "<doc><a>Some text</a>\n <b>Some more</b>\n</doc>"

	REXML::Document.new(text, { :compress_ 

whitespace => :all,

	                        :ignore_ 

whitespace_nodes => :all }).to_s

	# => "<doc><a>Some text</a><b>Some more</b></doc>"
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Guessing a Document's Encoding
Inhaltsvorschau
Credit: Mauro Cicio
You want to know the character encoding of a document that doesn't declare it explicitly.
Use the Ruby bindings to the libcharguess library. Once it's installed, using libcharguess is very simple.
Here's an XML document written in Italian, with no explicit encoding:
	doc = %{<?xml version="1.0"?>

	     <menu tipo="specialità" giorno="venerdì">

	    <primo_piatto>spaghetti al ragù</primo_piatto>

	        <bevanda>frappè</bevanda>

	     </menu>}
Let's find its encoding:
	require 'charguess'



	CharGuess::guess doc

	# => "windows-1252"
This is a pretty good guess: the XML is written in the ISO-8859-1 encoding, and many web browsers treat ISO-8859-1 as Windows-1252.
In XML, the character-encoding indication is optional, and may be provided as an attribute of the XML declaration in the first line of the document:
	<xml version="1.0" encoding="utf-8"?>
If this is missing, you must guess the document encoding to process the document. You can assume the lowest common denominator for your community (usually this means assuming that everything is either UTF-8 or ISO-8859-1), or you can use a library that examines the document and uses heuristics to guess the encoding.
As of the time of writing, there are no pure Ruby libraries for guessing the encoding of a document. Fortunately, there is a small Ruby wrapper around the Charguess library. This library can guess with 95% accuracy the encoding of any text whose charset is one of the following: BIG5, HZ, JIS, SJIS, EUC-JP, EUC-KR, EUC-TW, GB2312, Bulgarian, Cyrillic, Greek, Hungarian, Thai, Latin1, and UTF8.
Note that Charguess is not XML-or HTML-specific. In fact, it can guess the encoding of an arbitrary string:
	CharGuess::guess("\xA4\xCF")               # => "EUC-JP"
It's fairly easy to install libcharguess, since the library is written in portable C++. Unfortunately, it doesn't take care to put its header files in a standard location. This makes it a little tricky to compile the Ruby bindings, which depend on the charguess.h header. When you run
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Converting from One Encoding to Another
Inhaltsvorschau
Credit: Mauro Cicio
You want to convert a document to a given charset encoding (probably UTF-8).
If you don't know the document's current encoding, you can guess at it using the Charguess library described in the previous recipe. Once you know the current encoding, you can convert the document to another encoding using Ruby's standard iconv library.
Here's an XML document written in Italian, with no explicit encoding:
	doc = %{<?xml version="1.0"?>

	     <menu tipo="specialità" giorno="venerdì">

	    <primo_piatto>spaghetti al ragù</primo_piatto>

	       <bevanda>frappè</bevanda>

	     </menu>}
Let's figure out its encoding and convert it to UTF-8:
	require 'iconv'

	require 'charguess' # not necessary if input encoding is known



	input_encoding = CharGuess::guess doc                 # => "windows-1252"

	output_encoding = 'utf-8'



	converted_doc = Iconv.new(output_encoding, input_encoding).iconv(doc)



	CharGuess::guess(converted_doc) 	                  # => "UTF-8"
The heart of the iconv library is the Iconv class, a wrapper for the Unix 95 iconv( ) family of functions. These functions translate strings between various encoding systems. Since iconv is part of the Ruby standard library, it should be already available on your system.
Iconv works well in conjunction with Charguess: even if Charguess guesses the encoding a little bit wrong (such as guessing Windows-1252 for an ISO-8859-1 document), it always makes a good enough guess that iconv can convert the document to another encoding.
Like Charguess, the Iconv library is not XML-or HTML-specific. You can use libcharguess and iconv together to convert an arbitrary string to a given encoding.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Extracting All the URLs from an HTML Document
Inhaltsvorschau
You want to find all the URLs on a web page.
Do you only want to find links (that is, URLs mentioned in the HREF attribute of an A tag)? Do you also want to find the URLs of embedded objects like images and applets? Or do you want to find all URLs, including ones mentioned in the text of the page?
The last case is the simplest. You can use URI.extract to get all the URLs found in a string, or to get only the URLs with certain schemes. Here we'll extract URLs from some HTML, whether or not they're inside A tags:
	require 'uri'



	text = %{"My homepage is at

	<a href="http://www.example.com/">http://www.example.com/</a>, and be sure

	to check out my weblog at http://www.example.com/blog/. Email me at <a

	href="mailto:bob@example.com">bob@example.com</a>.} 

URI.extract(text)

	# => ["http://www.example.com/", "http://www.example.com/",

	#        "http://www.example.com/blog/.", "mailto:bob@example.com"]



	# Get HTTP(S) links only.

	URI.extract(text, ['http', 'https'])

	# => ["http://www.example.com/", "http://www.example.com/"

	#        "http://www.example.com/blog/."]
If you only want URLs that show up inside certain tags, you need to parse the HTML. Assuming the document is valid, you can do this with any of the parsers in the rexml library. Here's an efficient implementation using REXML's stream parser. It retrieves URLs found in the HREF attributes of A tags and the SRC attributes of IMG tags, but you can customize this behavior by passing a different map to the constructor.
	require 'rexml/document'

	require 'rexml/streamlistener'

	require 'set'



	class LinkGrabber

	  include REXML::StreamListener

	  attr_reader :links



	def initialize(interesting_tags = {'a' => %w{href}, 'img' => %w{src}}.freeze)

	   @tags = interesting_tags

	   @links = Set.new

	 end

	  def tag_start(name, attrs)

	    @tags[name].each do |uri_attr|

	      @links << attrs[uri_attr] if attrs[uri_attr]

	    end if @tags[name]

	  end



	  def parse(text)

	    REXML::Document.parse_stream(text, self)

	  end

	end



	grabber = 

LinkGrabber.new

	grabber.parse(text)

	grabber.links

	# => #<Set: {"http://www.example.com/", "mailto:bob@example.com"}>
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Transforming Plain Text to HTML
Inhaltsvorschau
You want to add simple markup to plaintext and turn it into HTML.
Use RedCloth, written by "why the lucky stiff" and available as the RedCloth gem. It extends Ruby's string class to support Textile markup: its to_html method converts Textile markup to HTML.
Here's a simple document:
	require 'rubygems'

	require 'redcloth'



	text = RedCloth.new %{Who would ever write "HTML":http://www.w3.org/MarkUp/

	markup directly?



	I mean, _who has the time_? Nobody, that's who:



	|_. Person |_. Has the time?        |

	|   Jake   |     No                 |

	|  Alice   |     No                 |

	|  Rodney  | Not since the accident |

	}



	puts text.to_html

	# <p>Who would ever write

	# <a href="http://www.w3.org/MarkUp/"><span class="caps">HTML</span></a>

	# markup directly?</p>

	#

	# <p>I mean, <em>who has the time</em>? Nobody, that&#8217;s who:</p>

	#

	# <table>

	#  <tr>

	#   <th>Person </th>

	#   <th>Has the time?        </th>

	# </tr>

	# …
The Textile version is more readable and easier to edit.
The Textile markup language lets you produce HTML without having to write any HTML. You just add punctuation to plain text, to convey what markup you'd like. Paragraph breaks are represented by blank lines, italics by underscores, tables by ASCII-art drawings of tables.
A text-based markup that converts to HTML is very useful in weblog and wiki software, where the markup will be edited many times. It's also useful for hiding the complexity of HTML from new computer users. We wrote this entire book using a Textile-like markup, though it was converted to Docbook instead of HTML.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Converting HTML Documents from the Web into Text
Inhaltsvorschau
You want to get a text summary of a web site.
The open-uri library is the easiest way to grab the content of a web page; it lets you open a URL as though it were a file:
	require 'open-uri'



	example = open('http://www.example.com/')

	# => #<StringIO:0xb7bb601c>



	html = example.read
As with a file, the read method returns a string. You can do a series of sub and gsub methods to clean the code into a more readable format.
	plain_text = 

html.sub(%r{<body.*?>(.*?)</body>}mi, '\1').gsub(/<.*?>/m, ' ').

	    gsub(%r{(\n\s*){2}}, "\n\n")
Finally, you can use the standard CGI library to unescape HTML entities like &lt; into their ASCII equivalents (<):
	require 'cgi'

	plain_text = CGI.unescapeHTML(plain_text)
The final product:
	puts plain_text

	# Example 

Web Page

	#

	# You have reached this web page by typing "example.com",

	# "example.net",

	# or "example.org" into your web browser.

	# These domain names are reserved for use in documentation and are not available

	# for registration. See RFC

	# 2606 , Section 3.
The open-uri library extends the open method so that you can access the contents of web pages and FTP sites with the same interface used for local files.
The simple regular expression substitutions above do nothing but remove HTML tags and clean up excess whitespace. They work well for well-formatted HTML, but the web is full of mean and ugly HTML, so you may consider taking a more involved approach. Let's define a HTMLSanitizer class to do our dirty business.
An HTMLSanitizer will start off with some HTML, and through a series of search-and-replace operations transform it into plain text. Different HTML tags will be handled differently. The contents of some HTML tags should simply be removed in a plaintext rendering. For example, you probably don't want to see the contents of <head> and <script> tags. Other tags affect what the rendition should look like, for instance, a <p> tag should be represented as a blank line:
	require 'open-uri'

	require 'cgi'



	class HTMLSanitizer

	  attr_accessor :html



	  @@ignore_tags = ['head', 'script', 'frameset' ]

	  @@inline_tags = ['span', 'strong', 'i', 'u' ]

	  @@block_tags = ['p', 'div', 'ul', 'ol' ]
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
A Simple Feed Aggregator
Inhaltsvorschau
Credit: Rod Gaither
XML is the basis for many specialized langages. One of the most popular is RSS, an XML format often used to store lists of articles from web pages. With a tool called an aggregator, you can collect weblog entries and articles from several web sites' RSS feeds, and read all those web sites at once without having to skip from one to the other. Here, we'll create a simple aggregator in Ruby.
Before aggregating RSS feeds, let's start by reading a single one. Fortunately we have several options for parsing RSS feeds into Ruby data structures. The Ruby standard library has built-in support for the three major versions of the RSS format (0.9, 1.0, and 2.0). This example uses the standard rss library to parse an RSS 2.0 feed and print out the titles of the items in the feed:
	require 'rss/2.0'

	require 'open-uri'



	url = 'http://www.oreillynet.com/pub/feed/1?format=rss2'

	feed = RSS::Parser.parse(open(url).read, false)

	puts "=== Channel: #{feed.channel.title} ==="

	feed.items.each do |item|

	  puts item.title

	  puts " (#{item.link})"

	  puts

	  puts item.description

	end

	# === Channel: O'Reilly Network Articles ===

	# How to Make Your Sound Sing with Vocoders

	# (http://digitalmedia.oreilly.com/2006/03/29/vocoder-tutorial-and-tips.html)

	# …
Unfortunately, the standard rss library is a little out of date. There's a newer syndication format called Atom, which serves the same purpose as RSS, and the rss library doesn't support it. Any serious aggregator must support all the major syndication formats.
So instead, our aggregator will use Lucas Carlson's Simple RSS library, available as the simple-rss gem. This library supports the three main versions of RSS, plus Atom, and it does so in a relaxed way so that ill-formed feeds have a better chance of being read.
Here's the example above, rewritten to use Simple RSS. As you can see, only the name of the class is different:
	require 'rubygems'

	require ' 

simple-rss'

	url = 'http://www.oreillynet.com/pub/feed/1?format=rss2'

	feed = RSS::Parser.parse(open(url), false)

	puts "=== Channel: #{feed.channel.title} ==="

	feed.items.each do |item|

	  puts item.title

	  puts " (#{item.link})"

	  puts

	  puts item.description

	end
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Chapter 12: Graphics and Other File Formats
Inhaltsvorschau
Hundreds of standards exist for storing structured data in text or binary files. Some of these are so popular that we've devoted entire chapters to them (Chapters 11 and 13). Some are so simple that you can process them with the ad hoc techniques listed in Chapters 1 and 6. This chapter is a grab bag that tries to cover the rest of the field.
We focus especially on graphics, probably the most common binary files. Ruby lacks a mature image manipulation library like the Python Imaging Library, but it does have bindings to ImageMagick and GraphicsMagick, popular and stable C libraries. The RMagick library provides the same interface against ImageMagick and GraphicsMagick, so it doesn't matter which one you use.
You can get RMagick by installing the RMagick or Rmagick-win32 gem. Unfortunately, the C libraries themselves are difficult to install: they have a lot of dependencies, especially if you want to process image formats like GIF and PostScript. The installation FAQ can help (http://rmagick.rubyforge.org/install-faq.html). On Debian GNU/Linux, you can just install the imagemagick package and then the RMagick gem.
The first recipes in this chapter show how to use RMagick to manipulate and convert images (on the question of finding images, see Recipe 16.2). Then it gets miscellaneous: we cover encryption, archive formats, Excel spreadsheets, and music files. We don't have space to cover every popular file format, but this chapter should give you an idea of what's out there. If this chapter lacks a recipe on your file format of choice, you may be able to find a Ruby library for it on the RAA, or by doing a web search for ruby [file format name].
Credit: Antonio Cangiano
Given an image, you want to create a smaller image to serve as a thumbnail.
Use RMagick, available from the rmagick or rmagick-win32 gems. Its Magick module gives you a simple but versatile way to manipulate images. The class Magick::Image lets you resize images four different ways: with resize, scale, sample, or thumbnail
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Thumbnailing Images
Inhaltsvorschau
Credit: Antonio Cangiano
Given an image, you want to create a smaller image to serve as a thumbnail.
Use RMagick, available from the rmagick or rmagick-win32 gems. Its Magick module gives you a simple but versatile way to manipulate images. The class Magick::Image lets you resize images four different ways: with resize, scale, sample, or thumbnail.
All four methods accept a pair integer values, corresponding to the width and height in pixels of the thumbnail you want. Here's an example that uses resize: it takes the file myimage.jpg and makes a thumbnail of it 100 pixels wide by 100 pixels tall:
	require 'rubygems'

	require 'RMagick'



	img = 

Magick::Image.read('myimage.jpg').first

	width, height = 100, 100

	thumb = img.resize(width, height)

	thumb.write('mythumbnail.jpg')
The class method Image.read, used in the Solution, receives an image filename as an argument and returns an array of Image objects. You obtain the first (and, usually, only) element through Array#first.
The code given in the Solution produces a thumbnail that is 100 pixels by 100, no matter what dimensions the original image had. If the original image was a square, its proportions will be maintained. But if the initial image was a rectangle, squishing it into a 100 x 100 box will distort it.
If all your thumbnails need to be the same size, you might be willing to live with this distortion. But to maintain the proportions between the longest and shortest dimensions, you should define your thumbnail's width and height in terms of the original image's aspect ratio. You can get the image's original width and height by using its accessor methods, Magick:: Image#columns and Magick:: Image#rows.
A simpler solution is to pass resize a floating-point number as a scaling factor. This changes the image's size without altering the aspect ratio. Here's how to generate an image that is 15% the size of the original:
	scale_factor = 0.15

	thumb = img.resize(scale_factor)

	thumb.write("mythumbnail.jpg")
To impose a maximum size on an image without altering its aspect ratio, use
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Adding Text to an Image
Inhaltsvorschau
Credit: Antonio Cangiano
You want to add some text to an image—perhaps a caption or a copyright statement.
Create an RMagick Draw object and call its annotate method, passing in your image and the text.
The following code adds the copyright string '&#169; NPS' to the bottom-right corner of the canyon.png image. It also specifies the font, the text color and size, and other features of the text:
	require 'rubygems'

	require 'RMagick'



	img = Magick::Image.read('canyon.png').first

	my_text = "\251 NPS"



	copyright = Magick::Draw.new

	copyright.annotate(img, 0, 0, 3, 18, my_text) do

	 self.font = 'Helvetica'

	 self.pointsize = 12

	 self.font_weight = Magick::BoldWeight

	 self.fill = 'white'

	 self.gravity = Magick::SouthEastGravity

	end

	img.write(' 

canyoncopyrighted.png')
The resulting image looks like Figure 12-1.
Figure 12-1: With a copyright message in the bottom-right corner
The annotate method takes a code block that sets properties on the Magick::Draw object, describing how the annotation should be done. You can also set the properties on the Draw object before calling annotate. This code works the same as the code given in the Solution:
	require 'rubygems'

	require 'RMagick'



	img = Magick::Image.read("canyon.png").first

	my_ 

text = '\251 NPS'



	copyright = Magick::Draw.new

	copyright.font = 'Helvetica'

	copyright.pointsize = 12

	copyright.font_weight = Magick::BoldWeight

	copyright.fill = 'white'

	copyright.gravity = Magick::SouthEastGravity

	copyright.annotate(img, 0, 0, 3, 18, my_text)

	img.write('canyoncopyrighted.png')
What do these attributes do?
  • The font attribute selects the font type from among those installed on your system. You can also specify the path to a specific font that is in a nonstandard location (e.g., "/home/antonio/Arial.ttf").
  • pointsize is the font size in points (the default is 12). By default, there is one pixel per point, so you can just specify the font size in pixels.
  • font_weight accepts a WeightType
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Converting One Image Format to Another
Inhaltsvorschau
Credit: Antonio Cangiano
You want to convert an image to a different format.
With RMagick, you can just read in the file and write it out with a different extension. This code converts a PNG file to JPEG format:
	require 'rubygems'

	require 'RMagick'



	img = Magick::Image.read('myimage.png').first

	img.write('myimage.jpg')
As seen in the previous two recipes, Magick::Image.read receives the PNG image and returns an array of Image objects, from which we select the first and only image.
RMagick lets us convert the file into a JPEG by simply changing the filename's extension when we call the write method.
The underlying C library, ImageMagick or GraphicsMagick, has three ways of determining the format of image files:
  • Checking an explicitly specified format prefix: for example, "GIF:myimage.jpg" indicates that the file myimage contains a GIF image, even though the file extension says otherwise.
  • Looking inside the file for a "magic number", a set of bytes that indicates the format.
  • Checking the file extension: for example, "myphoto.gif" is presumably a GIF file.
Although the format prefix takes precedence over the magic number, RMagick won't be fooled by an incorrect prefix. Eventually it will have to parse the image file, and the format mismatch will be revealed:
	Magick::Image.read("JPG:myimage.png")

	# Magick::ImageMagickError: Not a JPEG file: starts with 0x89 0x50 `myimage.png':
When you write an image to an output file, you can choose the output format by specifying a file extension or a prefix.
	img = Magick::Image.read("myimage.png").first

	img.write("myimage.jpg")                 # Writes a JPEG

	img.write("myimage.gif")                 # Writes a GIF

	img.write("JPG:myimage")                 # Writes a JPEG

	img.write("JPG:myimage.gif")             # Writes a JPEG
You can also get or set the file format of an image by calling the Image#format or Image#format= methods:
	img.format                               # => "PNG"

	img.format = "GIF"

	img.format                               # => "GIF"
Of course, RMagick can't read to and write from every graphical file format in existence. How can you tell whether your version of RMagick knows how to write a particular file format?
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Graphing Data
Inhaltsvorschau
You want to convert a bunch of data into a graph; usually a line chart, bar chart, or pie chart.
Use the Gruff library, written by Geoffrey Grosenbach. Install the gruff gem and build a Gruff object corresponding to the type of graph you want (for instance, Gruff::Line, Gruff::Bar,or Gruff::Pie). Add a dataset to the graph by passing data a label and an array of data points.
Here's code to create a graph that compares the running times of different sorts of algorithms:
	require 'rubygems'

	require 'gruff'



	g = Gruff::Line.new(600)                 # The graph will be 600 pixels wide.

	g.title = 'Algorithm running times'

	g.theme_37signals                        # The best-looking theme, in my opinion.



	range = (1..101)

	g.data('Constant', range.collect { 1 })

	g.data('O(log n)', range.collect { |x| Math::log(x) / Math::log(2) })

	g.data('O(n)', range.collect { |x| x })

	g.data('O(n log n)', range.collect { |x| x * Math::log(x) / Math::log(2) })



	g.labels = {10 => 'n=10', 50 => 'n=50', 100 => 'n=100' }

	g.write('algorithms.png')
Figure 12-3 shows the graph it produces.
Figure 12-3: A line chart
Here's code to create a pie chart (shown in Figure 12-4). Note that the numbers given for the datasets don't have to add up to 100. Gruff automatically scales the the pie chart to display the right proportions.
	p = 

Gruff::Pie.new

	p.theme_monochrome

	p.title = "Survey: the value of pi"

	p.data('"About three"', [3])

	p.data('3.14', [8])

	p.data('3.1415', [11])

	p.data('22/7', [8])



	p.write('pipie.png')
Figure 12-4: A pi chart
Most of the time, programmers who need a graphing library need a simple graphing library: one that lets them easily produce a quick pie, line, or bar graph. Gruff works well for graphing simple datasets, but it doesn't have the functionality of a fullfledged math program.
Gruff's interface for customizing the display of datasets also leaves something to be desired. Instead of letting you tweak the colors individually, it provides a number of themes that package together a background image, a text color, and a number of colors used in the graphs. Unfortunately, most of the provided themes are ugly
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Adding Graphical Context with Sparklines
Inhaltsvorschau
You want to display a small bit of statistical context—a trend or a set of percentages—in the middle of a piece of text, without breaking up the flow of the text.
Install the sparklines gem (written by Geoffrey Grosenbach)and create a sparkline: a tiny embedded graphic that can go next to a piece of text without being too intrusive. If you're creating an HTML page, the image doesn't even need to have its own file: it can be embedded directly in the HTML.
This code creates a sparkline for a company's stock price, and embeds it in HTML after the company's stock symbol:
	require 'rubygems'

	require ' 

sparklines'

	require 'base64'



	def embedded_sparkline

	  %{<img src="data:image/png;base64,#{Base64.encode64(yield)}">}

	end



	# This method scales data so that the smallest item becomes 0 and the

	# largest becomes 100.

	def scale(data)

	  min, max = data.min, data.max

	  data.collect { |x| (x - min) / (max - min) * 100}

	end



	# Randomly generate closing prices for the past month.

	prices = [rand(10)]

	30.times { prices << prices.last + (rand - 0.5) }



	# Generate HTML containing a stock graph as an embedded sparkline.

	sparkline = embedded_sparkline { Sparklines.plot(scale(prices)) }

	open('stock.html', 'w') do |f|

	  f << "Is EvilCorp (NASDAQ:EVIL #{sparkline}) poised for a comeback?"

	end
This code generates HTML that renders as shown in Figure 12-5.
Figure 12-5: A stock price history sparkline
Since it has no labels, the meaning of the sparkline must be determined from context. In this case, the graphic follows a stock symbol, so you can guess that it graphs the stock price. In a different context, the sparkline for EvilCorp might be the company's reported earnings over time, or the results of a poll that tracks public opinion of the company.
Embedded sparklines won't show up in Internet Explorer, but if you're using Rails you can use the sparklines_generator gem to put cross-browser sparklines in your views.
Sparklines are a way of graphically conveying information that would take lots of text to explain. They were invented by interface expert Edward Tufte, who describes them as "intense, simple, word-sized graphics." As implemented in the Ruby Sparklines library, a sparkline displays a small graph that shows a set of related numbers or a single percentage.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Strongly Encrypting Data
Inhaltsvorschau
You want to encrypt some data: to keep it private, or to keep it safe when sent through an insecure medium like email.
There are at least two good symmetric-key cryptography libraries for Ruby: Pelle Braendgaard's EzCrypto (available as the ezcrypto gem)and Richard Kernahan's Crypt (a third-party download).
EzCrypto is a user-friendly Ruby wrapper around the OpenSSL library, which you may need to install separately. Here's how to encrypt and decrypt a string with EzCrypto:
	require 'rubygems'

	require 'ezcrypto'



	plaintext = '24.9195N 17.821E'



	ezcrypto_key = EzCrypto::Key.with_password 'My secret key', 'salt string'

	ezcrypto_ciphertext = ezcrypto_key.encrypt(plaintext)

	# => "F\262\260\273\217\tR\351\362-\021-a\336\324Qc…" 

ezcrypto_key.decrypt(ezcrypto_ciphertext)

	# => "24.9195N 17.821E"
The Crypt library gives each encryption algorithm its own class, so you need to decide which you want to use. I'll use the AES/Rijndael algorithm: all the other algorithms have the same interface.
	require 'crypt/rijndael'



	aes_key = Crypt::Rijndael.new('My secret key')

	aes_cyphertext = aes_key.encrypt_string(plaintext)

	# => "\e\003\203\030]\203\t\346…"



	aes_key.decrypt_string(aes_cyphertext)

	# => "24.9195N 17.821E"
EzCrypto is available as a gem (ezcrypto), and it's fast because the actual encryption and decryption happens in the C OpenSSL libraries. Crypt is a pure Ruby implementation, so it's slower, but you don't have to worry about OpenSSL being installed.
EzCrypto and Crypt both implement several symmetric key algorithms. With EzCrypto, you can also specify the algorithm to use when you create an EzCrypto key. With Crypt, you need to instantiate the appropriate algorithm's class:
	# EzCrypto example

	blowfish_key = EzCrypto::Key.with_password('My secret password', 'salt string',

	                                           :algorithm=>'blowfish')

	# Crypt example

	require 'crypt/blowfish'

	blowfish_key = Crypt::Blowfish.new('My secret password')
The Crypt classes provide some convenience methods for encrypting and decrypting files and streams. The
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Parsing Comma-Separated Data
Inhaltsvorschau
You have a plain-text string in a comma-delimited format. You need to parse this string, either to build a data structure or to perform some operation on the data and write it back out.
The built-in csv library can parse most common character-delimited formats. The FasterCSV library, available as the fastercsv gem, improves on csv's performance and interface. I'll show you both, but I recommend fastercsv unless you can't use any software at all outside the standard library.
CSV::Reader.parse and FasterCSV.parse work the same way: they accept a string or an open file as an argument, and yield each parsed row of the comma-delimited file as an array. The csv yields a Row object that acts like an array full of Column objects. FasterCSV just yields an array of strings.
	require 'csv'

	primary_colors = "red,green,blue\nred,yellow,blue"



	CSV::Reader.parse(primary_colors) { |row| row.each { |cell| puts cell }}

	# red

	# green

	# blue

	# red

	# yellow

	# blue



	require 'rubygems'

	require 'faster_csv'

	shakespeare = %{Sweet are the uses of adversity,As You Like It

	"We few, we happy few",Henry V

	"Seems, madam! nay it is; I know not ""seems.""",Hamlet}



	FasterCSV.parse(shakespeare) { |row| puts "'#{row[0]}' -- #{row[1]}"}

	# 'Sweet are the uses of adversity' -- As You Like It

	# 'We few, we happy few' -- Henry V

	# 'Seems, madam! nay it is; I know not "seems."' -- Hamlet
Comma-delimited formats are among the most basic portable file formats. Unfortunately, they're also among the least standardized. There are many different formats, and some are internally inconsistent.
FasterCSV and the csv library can't parse every comma-delimited format, but they will parse common formats like the one used by Microsoft Excel, and they're your best tool for making sense of the myriad.
FasterCSV and csv both model a comma-delimited file as a nested array of strings. The csv library's CSV class uses Row objects and Column objects instead of arrays and strings, but it's the same idea. The terminology is from the spreadsheet world—understand-ably, since a CSV file is a common way of portably storing spreadsheet data.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Parsing Not-Quite-Comma-Separated Data
Inhaltsvorschau
You need to parse a plain- text string or file that's in a format similar to commadelimited format, but its delimiters are some strings other than commas and newlines.
When you call a CSV::Reader method, you can specify strings to act as a row separator (the string between each Row) and a field separator (the string between each Column). You can do the same with simulated keyword arguments passed into FasterCSV.parse. This should let you parse most formats similar to the comma-delimited format:
	require 'csv'



	pipe_separated="1|2ENDa|bEND" 

CSV::Reader.parse(pipe_separated, '|', 'END') { |r| r.each { |c| puts c } }

	# 1

	# 2

	# a

	# b



	require 'rubygems'

	require 'faster_csv'

	FasterCSV.parse(pipe_separated, :col_sep=>'|', :row_sep=>'END') do |r|

	  r.each { |c| puts c }

	end

	# 1

	# 2

	# a

	# b
Value-delimited formats tend to differ along three axes:
  • The field separator (usually a single comma)
  • The row separator (usually a single newline)
  • The quote character (usually a double quote)
Like Reader methods, Writer methods accept custom values for the field and row separators.
	data = [[1,2,3],['A','B','C'],['do','re','mi']]



	open('first3.csv', 'w') do |output|

	  CSV::Writer.generate(output, ':', '-END-') do |writer|

	    data.each { |x| writer << x }

	  end

	end

	open('first3.csv') { |input| input.read() }

	# => "1:2:3-END-A:B:C-END-do:re:mi-END-"



	FasterCSV.open('first3.csv', 'w', :col_sep=>':', :row_sep=>'-END-') do |output|

	  data.each { |x| output << x }

	end

	open('first3.csv') { |input| input.read() }

	# => "1:2:3-END-A:B:C-END-do:re:mi-END-"
It's rare that you'll need to override the quote character, and neither csv nor fastercsv will let you do it. Both libraries' quote characters are hardcoded to the double-quote character. If you need to parse a format that has different quote character, the simplest thing to do is subclass FasterCSV and override its init_parsers method.
Change the regular expression assigned to @parsers[:csv_row], replacing all double quotes with the quote character you want. The most common alternate quote character is the single quote: to get that, you'd have an
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Generating and Parsing Excel Spreadsheets
Inhaltsvorschau
Your program needs to parse data from Excel spreadsheets, or generate new Excel spreadsheets.
To generate Excel files, use the spreadsheet library, available as a third-party gem (see the See Also section below for where to get it). With it you can create simple Excel spreadsheets. As of this writing, spreadsheet does not support formulas or large spreadsheets (seven megabytes is the limit).
This code creates an Excel spreadsheet containing some random numbers with a total, and saves it to disk:
	require 'rubygems'

	require 'spreadsheet/excel'



	SUM_SPREADSHEET = 'sum.xls'

	workbook = Spreadsheet::Excel.new(SUM_SPREADSHEET)

	worksheet = workbook.add_worksheet('Random numbers and their sum.')

	sum = 0

	random_numbers = (0..9).collect { rand(100) }

	worksheet.write_column(0, 0, random_numbers)



	format = workbook.add_format(:bold => true)

	worksheet.write(10, 0, "Sum:", format)

	worksheet.write(10, 1, random_numbers.inject(0) { |sum, x| sum + x })

	workbook.close
To parse an Excel file, use the parseexcel library, also available as a third-party download. It can parse simple data out of the Excel file format. This code parses the Excel file generated by the previous code:
	require ' 

parseexcel/parser'

	workbook = Spreadsheet::ParseExcel::Parser.new.parse(SUM_SPREADSHEET)



	worksheet = workbook.worksheet(0)

	sum = (0..9).inject(0) do |sum, row|



	  sum + worksheet.cell(row, 0).value.to_i

	end



	worksheet.cell(10, 0).value                              # => "Sum:"

	worksheet.cell(10, 1).value                              # => 602.0

	sum                                                      # => 602
Like spreadsheet, parseexcel doesn't recognize spreadsheet formulas.
The comma-separated file is the lingua franca for spreadsheet data, but sometimes you must deal with real spreadsheet files. You can save other people's time by accepting their Excel spreadsheets as input, instead of insisting they convert everything to CSV for you. And nothing impresses manager types like an automatically generated spreadsheet file they can poke at.
The spreadsheet and
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Compressing and Archiving Files with Gzip and Tar
Inhaltsvorschau
You want to write compressed data to a file to save space, or uncompress the contents of a compressed file. If you're compressing data, you might want to compress multiple files into a single archive file.
The most common compression format on Unix systems is gzip. Ruby's zlib library lets you read to and write from gzipped I/O streams as though they were normal files. The most useful classes in this library are GzipWriter and GzipReader.
Here's GzipWriter being used to create a compressed file, and GzipReader decompressing the same file:
	require ' 

zlib'



	file = 'compressed.gz'

	Zlib::GzipWriter.open(file) do |gzip|

	  gzip << "For my next trick, I'll be written to a compressed file."

	  gzip.close

	end



	open(file, 'rb') { |f| f.read(10) }

	# => "\037\213\010\000\201\2766D\000\003"



	Zlib::GzipReader.open(file) { |gzip| gzip.read }

	# => "For my next trick, I'll be written to a compressed file."
GzipWriter and GzipReader are most commonly used to write to files on disk, but you can wrap any file-like object in the appropriate class and automatically compress everything you write to it, or decompress everything you read from it.
The following code works the same way as the compression code in the Solution, but it's more flexible: the File object that's passed into the Zlib::GzipWriter constructor could just as easily be a Socket or other file-like object.
	open('compressed.gz', 'wb') do |file|

	  gzip = Zlib::GzipWriter.new(file)

	  gzip << "For my next trick, I'll be written to a compressed file."

	  gzip.close

	end
If you need to compress or decompress a string, use the Zlib::Deflate or Zlib::Inflate classes rather than constructing a StringI0 object:
	deflated = Zlib::Deflate.deflate("I'm a compressed string.")

	# => "x\234\363T\317UHTH…"

	Zlib::Inflate.inflate(deflated)

	# => "I'm a compressed string."

Tar files

Gzip compresses a single file. What if you want to smash multiple files together into a single archive file? The standard archive format for Unix is
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Reading and Writing ZIP Files
Inhaltsvorschau
You want to create or examine a ZIP archive from within Ruby code.
Use the rubyzip gem. Its Zip module gives you several ways of putting files into ZIP archives, and taking them out again. The simplest interface is the Zip::ZipFileSystem, which duplicates most of the File and Dir operations within the context of a ZIP file. You can use this to create ZIP files:
	require 'rubygems'

	require 'zip/zipfilesystem'



	Zip::ZipFile.open('zipfile.zip', Zip::ZipFile::CREATE) do |zip|

	  zip.file.open('file1', 'w') { |f1| f1 << 'This is file 1.' }

	  zip.dir.mkdir('subdirectory')

	  zip.file.open('subdirectory/file2', 'w') { |f1| f1 << 'This is file 2.' }

	end
You can use the same interface to read a ZIP file. Here's a method that uses the equivalent of Dir#foreach to recursively print out the contents of a ZIP file:
	def process_zipfile(zip, path='')

	  if zip.file.file? path

	    puts %{#{path}: "#{zip.read(path)}"}

	  else

	    unless path.empty?

	      path += '/'

	      puts path

	    end

	    zip.dir.foreach(path) do |filename|

	      process_zipfile(zip, path + filename)

	    end

	  end

	end
And here it is running against the ZIP file I just created:
	Zip::ZipFile.open('zipfile.zip') do |zip|

	  process_zipfile(zip)

	end

	# subdirectory/

	# subdirectory/file2: "This is file 2."

	# file1: "This is file 1."
ZIP, or PKZip, is the most popular compression format on Windows. As seen in the previous recipe, Unix separates the tasks of stuffing several files into a single archive (tar), and compressing the resulting file (gzip). On Windows, ZIP files perform both tasks. If you want to compress a single file, you need to put it into a ZIP file all by itself.
The rubyzip library provides several interfaces for creating and reading ZIP files. Zip::ZipFileSystem is the easiest for most programmers: in the example above, zip.file has about the same interface as the File class, and zip.dir is similar to the Dir class. The analogy holds because a ZIP file actually contains a tiny filesystem inside it.
If you're porting Java code, or you're already familiar with Java's
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Reading and Writing Configuration Files
Inhaltsvorschau
You want to store your application's configuration on disk, in a format parseable by Ruby but easily editable by someone with a text editor.
Put your configuration into a data structure, and write the data structure to disk as YAML. So long as you only use built-in Ruby data types (strings, numbers, arrays, hashes, and so on), the YAML file will be human-readable and -editable.
	require 'yaml'

	configuration = { 'color' => 'blue',

	                  'font' => 'Septimus',

	                  'font-size' => 7 }

	open('text.cfg', 'w') { |f| YAML.dump(configuration, f) }



	open('text.cfg') { |f| puts f.read }

	# --

	# font-size: 7

	# color: blue

	# font: Septimus



	open('text.cfg') { |f| YAML.load(f) }

	# => {"font-size"=>7, "color"=>"blue", "font"=>"Septimus"}
It's easy for a user to edit this: it's just a colon-separated, line-delimited set of key names and values. Not a problem, even for a relatively unsophisticated user.
YAML is a serialization format, designed to store data structures to disk and read them back later. But there's no reason why the data structures can't be modified by other programs while they're on disk. Since simple YAML files are human-editable, they make good configuration files.
A YAML file typically contains a single data structure. The most common structures for configuration data are a hash (seen in the Solution) and an array of hashes.
	configuration = [ { 'name' => 'Alice', 'donation' => 50 },

	                  { 'name' => 'Bob', 'donation' => 15, 'currency' => "EUR" } ]

	open('donors.cfg', 'w') { |f| YAML.dump(configuration, f) }

	open('donors.cfg') { |f| puts f.read }

	# ---

	# - name: Alice

	#   donation: 50

	# - name: Bob

	#   donation: 15

	#   currency: EUR
In Recipe 5.1 we advise saving memory by using symbols as hash keys instead of strings. If your hash is going to be converted into human-editable YAML, you should always use strings. Otherwise, people editing the YAML may become confused. Compare the following two bits of YAML:
	puts { 'measurements' => 'metric' }.to_yaml

	# ---

	# measurements: metric

	puts { :measurements => :metric }.to_yaml

	# ---

	# :measurements: :metric
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Generating PDF Files
Inhaltsvorschau
You want to create a text or graphical document as a PDF, where you have complete control over the layout.
Use Austin Zeigler's PDF::Writer library, available as the pdf-writer gem. Its API gives you fine-grained control over the placement of text, images, and shapes.
This code uses PDF::Writer to produce a simple flyer with an image and a border (Figure 12-7). It assumes you've got a graphic called sue.png to insert into the document:
Figure 12-7: The flyer
	require 'rubygems'

	require ' 

pdf/writer'                                   # => false



	# Putting "false" on the next line suppresses a huge output dump when

	# you run this code in irb.

	 

pdf = PDF::Writer.new; false



	pdf.text("LOST\nDINOSAUR", :justification => :center, :font_size => 42,

	         :left => 50, :right => 50)

	pdf.image("sue.png", :left=> 100, :justification => :center, :resize => 0.75)

	pdf.text(%{Three-year-old <i>Tyrannosaurus rex</i>\nSpayed\nResponds to "Sue"},

	         :left => 80, :font_size => 20, :justification => :left)

	pdf.text("(555) 010-7829", :justification => :center, :font_size => 36)



	pdf.rectangle(pdf.left_margin + 25, pdf.y-25,

	              pdf.margin_width-50, pdf.margin_height-pdf.y+50).stroke; false



	pdf.save_as('flyer.pdf')
So long as you're only calling Writer#text and Writer#image, PDF generation is easy. PDF automatically adds new text and images to the bottom of the current text, creating new pages as needed.
It gets tricky when you want to do something more complex, like draw shapes. Then you need to specify the placement and dimensions in coordinates.
Take as an example the Writer#rectangle call in the Solution:
	pdf.rectangle(pdf.left_margin, pdf.y-25,

	            pdf.margin_width, pdf.margin_height-pdf.y+25).stroke
The first two arguments are coordinates: the left edge of the rectangle and the bottom edge of the rectangle. The second two arguments are the width and height of the rectangle.
The width is simple enough: my box starts at the left margin and its width is
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Representing Data as MIDI Music
Inhaltsvorschau
You want to represent a series of data points as a musical piece, or just create music algorithmically.
Jim Menard's midilib library makes it easy to generate MIDI music files from Ruby. It's available as the midilib gem.
Here's a simple method for visualizing a list of numbers as a piano piece. The largest number in the list is mapped to the highest note on the piano keyboard (MIDI note 108), and the smallest number to the lowest note (MIDI note 21).
	require 'rubygems'

	require 'midilib'                                        # => false



	class Array

	  def to_midi(file, note_length='eighth')



	    midi_max = 108.0

	    midi_min = 21.0



	    low, high = min, max

	    song = MIDI::Sequence.new



	    # Create a new track to hold the melody, running at 120 beats per minute.

	    song.tracks << (melody = MIDI::Track.new(song))

	    melody.events << 

MIDI::Tempo.new(MIDI::Tempo.bpm_to_mpq(120))



	    # Tell channel zero to use the "piano" sound.

	    melody.events << MIDI::ProgramChange.new(0, 0)



	    # Create a series of note events that play on channel zero.

	    each do |number|

	      midi_note = (midi_min + ((number-midi_min) * (midi_max-low)/high)).to_i

	      melody.events << MIDI::NoteOnEvent.new(0, midi_note, 127, 0)

	      melody.events << MIDI::NoteOffEvent.new(0, midi_note, 127,

	                                              song.note_to_delta(note_length))

	    end



	    open(file, 'w') { |f| song.write(f) }

	  end

	end
Now you can get an audible representation of any list of numbers:
	((1..100).collect { |x| x ** 2 }).to_midi('squares.mid')
The midilib library provides a set of classes for modeling a MIDI file: you can parse a MIDI file, modify it with Ruby code, and write it back to disk.
A MIDI file is modeled by a Sequence object, which contains Track objects. A track is a mainly a series of Event objects: for instance, each note in the piece has a NoteOnEvent and a NoteOffEvent.
Array#to_midi works by transforming each number in the array into a corresponding MIDI note. A standard piano keyboard can produce notes ranging from MIDI note 21 to MIDI note 108, with middle C being at MIDI note 60.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Chapter 13: Databases and Persistence
Inhaltsvorschau
We all want to leave behind something that will outlast us, and Ruby processes are no exception. Every program you write leaves some record of its activity, even if it's just data written to standard output. Most larger programs take this one step further: they store data from one run in a structured file, so that on another run they can pick up where they left off. There are a number of ways to persist data, from simple to insanely complex.
Simple persistence mechanisms like YAML let you write Ruby data structures to disk and load them back later. This is great for simple programs that don't handle much data. Your program can store its entire state in a disk file, and load the file on its next invocation to pick up where it left off. If you never keep more data than can fit into memory, the simplest way to make it permanent is to store it with YAML, Marshal, or Madeleine, and reload it later (see Recipes 13.1, 13.2, and 13.3). Madeleine also lets you revisit the prior states of your data.
If your dataset won't fit in memory, you need a database: a way of storing data on disk (usually in an indexed binary format) and retrieving parts of it quickly. The Berkeley database is the simplest database we cover: it operates like a hash, albeit a hash potentially much bigger than any you could keep in memory (Recipe 13.6).
But when most people think of a "database" they think of a relational database: MySQL, Postgres, Oracle, SQLite, or the like. A persistence mechanism stores data as Ruby data structures, and a Berkeley DB stores data as a hash of strings. But relational databases store data in the form of structured records with typed fields.
Because the tables of a relational database can have a complex structure and contain gigabytes of data, their contents are not accessed like normal Ruby data structures. Instead they're queried with SQL, a special programming language based on relational algebra. Most of the development time that goes into Ruby database libraries is spent trying to hide this fact. Several libraries hide the details of communication between a Ruby program and a SQL database; the balance of this chapter is devoted to showing how to use them.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Serializing Data with YAML
Inhaltsvorschau
You want to serialize a data structure and use it later. You may want to send the data structure to a file, then load it into a program written in a different programming language.
The simplest way is to use the built-in yaml library. When you require yaml, all Ruby objects sprout to_ yaml methods that convert them to the YAML serialization format. A YAML string is human-readable, and it intuitively corresponds to the object from which it was derived:
	require 'yaml'

	

	10.to_yaml               # => "--- 10\n"

	'ten'.to_yaml            # => "--- ten\n"

	'10'.to_yaml             # => "--- \"10\"\n"
Arrays are represented as bulleted lists:
	puts %w{Brush up your Shakespeare}.to_yaml

	# --

	# - Brush

	# - up

	# - your

	# - Shakespeare
Hashes are represented as colon-separated key-value pairs:
	puts ({ 'star' => 'hydrogen', 'gold bar' => 'gold' }).to_yaml

	# --

	# star: hydrogen

	# gold bar: gold
More complex Ruby objects are represented in terms of their classes and member variables:
	require 'set'

	puts Set.new([1, 2, 3]).to_yaml

	# --- !ruby/object:Set

	# hash:

	#  1: true

	#  2: true

	#  3: true
You can dump a data structure to a file with YAML.dump, and load it back with YAML.load:
	users = [{:name => 'Bob', :permissions => ['Read']},

	         {:name => 'Alice', :permissions => ['Read', 'Write']}]

	

	# Serialize

	open('users', 'w') { |f| YAML.dump(users, f) }



	# And deserialize

	users2 = open("users") { |f| YAML.load(f) }

	# => [{:permissions=>["Read"], :name=>"Bob"},

	#     {:permissions=>["Read", "Write"], :name=>"Alice"}]
YAML implementations are available for Perl, Python, Java, PHP, JavaScript, and OCaml, so if you stick to the "standard" data types (strings, arrays, and so on), the serialized file will be portable across programming languages.
If you've ever used Python's pickle module or serialized a Java object, you know how convenient it is to be able to dump an object to disk and load it back later. You don't have to define a custom data format or write an XML generator: you just shove the object into a file or a database, and read it back later. The only downside is that the serialized file is usually a binary mess that can only be understood by the serialization library.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Serializing Data with Marshal
Inhaltsvorschau
You want to serialize a data structure to disk faster than YAML can do it. You don't care about the readability of the serialized data structure, or portability to other programming languages.
Use the Marshal module, built into Ruby. It works more or less like YAML, but it's much faster. The Marshal.dump method transforms a data structure into a binary string, which you can write to a file and reconstitute later with Marshal.load.
	Marshal.dump(10)                              # => "\004\010i\017"

	Marshal.dump('ten')                           # => "\004\010\"\010ten"

	Marshal.dump('10')                            # => "\004\010\"\a10"



	Marshal.load(Marshal.dump(%w{Brush up your Shakespeare}))

	# => ["Brush", "up", "your", "Shakespeare"]



	require 'set'

	Marshal.load(Marshal.dump(Set.new([1, 2, 3])))

	# => #<Set: {1, 2, 3}>
Marshal is what most programmers coming from other languages expect from a serializer. It's fast (much faster than yaml), and it produces unreadable blobs of binary data. It can serialize almost anything that yaml can (see Recipe 13.1 for examples), and it can also handle a few cases that yaml can't. For instance, you can use Marshal to serialize a reference to a class:
	Marshal.dump(Set)                 # =>"\004\010c\010Set"
Note that the serialized version of Set is little more than a reference to the class. Like YAML, Marshal depends on the presence of the original classes, and you can't deserialize a reference to a class you don't have. With YAML, you'll get an unresolved YAML::Object; with Marshal, you get an ArgumentError:
	#!/usr/bin/ruby -w



	Marshal.load("\004\010c\010Set")

	# ArgumentError: undefined class/module Set
Like YAML, Marshal only serializes data structures. It can't serialize Ruby code (like Proc objects), or resources allocated by other processes (like filehandles or database connections). However, the two libraries differ in their error handling. YAML tends to serialize as much as it can: it can serialize a File object, but when you deserialize it, you get an object that doesn't point to any actual file. Marshal just gives you an error when you try to serialize a file:
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Persisting Objects with Madeleine
Inhaltsvorschau
You want to store objects in RAM and persist them between independent executions of the program. This will let your program recall its state indefinitely and access it very quickly.
Use the Madeleine library available as the madeleine gem. It transparently persists any Ruby object that can be serialized with Marshal. Unlike a conventional database persistence layer, Madeleine keeps all of its objects in RAM at all times.
To use Madeleine, you have to decide which objects in your system need to be serialized, and which ones you might have saved to a database traditionally. Here's a simple Madeleine-backed program for conducting yes/no polls, in which agreement adds one to a total and disagreement subtracts one:
	#!/usr/bin/ruby -w

	# poll.rb

	require 'rubygems'

	require 'madeleine'



	class Poll

	  attr_accessor :name

	  attr_reader :total



	  def initialize(name)

	    @name = name

	    @total = 0

	  end



	  def agree

	    @total += 1

	  end



	  def disagree

	    @total -= 1

	  end

	end
So far there's been no Madeleine code, just a normal class with instance variables and accessors. But how will we store the state of the poll between invocations of the polling program? Since instances of the Poll class can be serialized with Marshall, we can wrap a Poll object in a MadeleineSnapshot, and keep it in a file:
	poll = SnapshotMadeleine.new('poll_data') do

	  Poll.new('Is Ruby great?')

	end
The system accessor retrieves the object wrapped by MadeleineSnapshot:
	if ARGV[0] == 'agree'

	  poll.system.agree

	elsif ARGV[0] == 'disagree'

	  poll.system.disagree

	end



	puts "Name: #{poll.system.name}"

	puts "Total: #{poll.system.total}"
You can save the current state of the object with take_snapshot:
	poll.take_snapshot
Here are a few sample runs of the poll.rb program:
	$ ruby poll.rb agree

	Name: Is Ruby great?

	Total: 1



	$ ruby poll.rb agree

	Name: Is Ruby great?

	Total: 2



	$ ruby poll.rb disagree

	Name: Is Ruby great?

	Total: 1
Recall this piece of code:
	poll = SnapshotMadeleine.new('poll_data') do

	  Poll.new('Is Ruby great?')

	end
The first time that code is run, Madeleine creates a directory called
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Indexing Unstructured Text with SimpleSearch
Inhaltsvorschau
You want to index a number of texts and do quick keyword searches on them.
Use the SimpleSearch library, available in the SimpleSearch gem.
Here's how to create and save an index:
	require 'rubygems'

	require 'search/simple'



	contents = Search::Simple::Contents.new

	contents << Search::Simple::Content.

	              new('In the beginning God created the heavens…',

	                  'Genesis.txt', Time.now)

	contents << Search::Simple::Content.new('Call me Ishmael…',

	                                    'MobyDick.txt', Time.now)

	contents << Search::Simple::Content.new('Marley was dead to begin with…',

	                                    'AChristmasCarol.txt', Time.now)



	searcher = Search::Simple::Searcher.load(contents, 'index_file')
Here's how to load and search an existing index:
	require 'rubygems'

	require 'search/simple'



	searcher = nil

	open('index_file') do |f|

	  searcher = Search::Simple::Searcher.new(Marshal.load(f), Marshal.load(f),

	                                          'index_file')

	end



	searcher.find_words(['begin']).results.collect { |result| result.name }

	# => ["AChristmasCarol.txt", "Genesis.txt"]
SimpleSearch is a library that makes it easy to do fast keyword searching on unstructured text documents. The index itself is represented by a Searcher object, and each document you feed it is a Content object.
To create an index, you must first construct a number of Content objects and a Contents object to contain them. A Content object contains a piece of text, a unique identifier for that text (often a filename, though it could also be a database ID or a URL), and the time at which the text was last modified. Searcher.load transforms a Contents object into a searchable index that gets serialized to disk with Marshal.
The indexer analyzes the text you gives it, removes stop words (like "a"), truncates words to their roots (so "beginning" becomes "begin"), and puts every word of the text into binary data structures. Given a set of words to find and a set of words to exclude, SimpleSearch uses these structures to quickly find a set of documents.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Indexing Structured Text with Ferret
Inhaltsvorschau
You want to perform searches on structured text. For instance, you might want to search just the headline of a news story, or just the body.
The Ferret library can tokenize and search structured data. It's a pure Ruby port of Java's Lucene library, and it's available as the ferret gem.
Here's how to create and populate an index with Ferret. I'll create a searchable index of useful Ruby packages, stored as a set of binary files in the ruby_packages/ directory.
	require 'rubygems'

	require 'ferret'



	PACKAGE_INDEX_DIR = 'ruby_packages/'

	Dir.mkdir(PACKAGE_INDEX_DIR) unless File.directory? PACKAGE_INDEX_DIR

	index = 

Ferret::Index::Index.new(:path => PACKAGE_INDEX_DIR,

	                                 :default_search_field => 'name|description')

	index << { :name => 'SimpleSearch',

	           :description => 'A simple indexing library.',

	           :supports_structured_data => false,

	           :complexity => 2 }

	index << { :name => ' 

Ferret',

	           :description => 'A Ruby port of the Lucene library.

	                            More powerful than SimpleSearch',

	           :supports_structured_data => true,

	           :complexity => 5 }
By default, queries against this index will search the "name" and "description" fields, but you can search against any field:
	index.search_each('library') do |doc_id, score|

	  puts index.doc(doc_id).field('name').data

	end

	# SimpleSearch

	# Ferret



	index.search_each('description:powerful AND supports_structured_data:true') do

	|doc_id, score|

	  puts index.doc(doc_id).field("name").data

	end

	# Ferret



	index.search_each("complexity:<5") do |doc_id, score|

	  puts index.doc(doc_id).field("name").data

	end

	# SimpleSearch
When should you use Ferret instead of SimpleText? SimpleText is good for unstructured data like plain text. Ferret excels at searching structured data, the kind you find in databases.
Relational databases are good at finding exact field matches, but not very good at locating keywords within large strings. Ferret works best when you need full text search but you want to keep some of the document structure. I've also had great success using Ferret to bring together data from disparate sources (some in databases, some not) into one structured, searchable index.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Using Berkeley DB Databases
Inhaltsvorschau
You want a simple, fast database that doesn't need a server to run.
Ruby's standard dbm library lets you store a database in a set of standalone binary files. It's not a SQL database: it's more like a fast disk-based hash that only stores strings.
	require 'dbm'



	DBM.new('random_thoughts') do |db|

	  db['tape measure'] =

	    "What if there was a tape measure you could use as a yo-yo?"

	  db[23] = "Fnord."

	end



	DBM.open('random_thoughts') do |db|

	  puts db['tape measure']

	  puts db['23']

	end

	# What if there was a tape measure you could use as a yo-yo?

	# Fnord.



	DBM.open('random_thoughts') { |db| db[23] }

	# TypeError: can't convert Fixnum into String



	Dir['random_thoughts.*']

	# => ["random_thoughts.pag", "random_thoughts.dir"]
The venerable Berkeley DB format lets you store enormous associative datasets on disk and quickly access them by key. It dates from before programming languages had built-in hash structures, so it's not as useful as it used to be. In fact, if your hash is small enough to fit in memory, it's faster to simply use a Ruby hash that you serialize to disk with Marshal.
If you do need to use a DBM object, you can treat it almost exactly like a Ruby hash: it supports most of the same methods.
There are many, many implementations of the Berkeley DB, and the file formats differ widely between versions, so DBM files are not very portable. If you're creating your own databases, you should use the generic dbm library. It provides a uniform interface to all the DBM implementations, using the best library you have installed on your computer.
Ruby also provides gdbm and sdbm libraries, interfaces to specific database formats, but you should only need these if you're trying to load a Berkeley DB file produced by some other program.
There's also the SleepyCat library, a more ambitious implementation of the Berkeley DB that implements features of traditional databases like transactions and locking. Its Ruby bindings are available as a third-party download. It's still much closer to a disk-based data structure than to a relational database, and the basic interface is similar to that of
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Controlling MySQL on Unix
Inhaltsvorschau
The standard Ruby database interfaces assume you're connecting to a preexisting database, and that you already have access to this database. You want to create and administer MySQL databases from within Ruby.
Sam Ruby came up with an elegant solution to this problem. The mysql method defined below opens up a pipe to a MySQL client program and sends SQL input to it:
	def mysql(opts, stream)

	  IO.popen("mysql #{opts}", 'w') { |io| io.puts stream }

	end
You can use this technique to create, delete, and administer MySQL databases:
	mysql '-u root -p[password]', <<-end

	  drop database if exists website_db;

	  create database website_db;

	  grant all on website_db.* to #{`id -un`.strip}@localhost;

	end
This solution looks so elegant because of the <<-end declaration, which allows you to end the string the same way you end a code block.
One shortcoming of this solution is that the IO.popen call opens up a one-way communication with the MySQL client. This makes it difficult to call SQL commands and get the results back. If that's what you need, you can use IO.popen interactively; see Recipe 23.1.
  • Recipe 23.1, "Scripting an External Program"
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Finding the Number of Rows Returned by a Query
Inhaltsvorschau
Writing a DBI program, you want an efficient way to see how many rows were returned by a query.
A do command returns the number of rows affected by the command, so that one's easy. To demonstrate, I'll create a database table that keeps track of my prized collection of lowercase letters:
	require 'cookbook_dbconnect'



	with_db do |c|



 	  c.do %{drop table if exists letters}



	  c.do %{create table letters(id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,

	                          letter CHAR(1) NOT NULL)}

	  letter_sql = ('a'..'z').collect.join('"),("')



	  c.do %{insert into letters(letter) values ("#{letter_sql}")}

	end

	# => 26
When you execute a query, you get back a StatementHandle object representing the request. If you're using a MySQL database, you can call rows on this object to get the number of rows in the result set:
	vowel_query = %{select id from letters where letter in ("a","e","i","o","u")}

	with_db do |c|

	  h = c.execute vowel_query

	  "My collection contains #{h.rows} vowels."

	end

	# => "My collection contains 5 vowels."
If you're not using MySQL, things are a bit trickier. The simplest thing to do is simply retrieve all the rows as an array, then use the array's size as the number of rows:
	with_db do |c|

	  vowels = c.select_all(vowel_query)

	  "My collection still contains #{vowels.size} vowels."

	end

	# => "My collection still contains 5 vowels."
But this can be disastrously inefficient; see below for details.
When you select some items out of a Ruby array, say with Array#grep, Ruby gives you the results in a brand new array. Once the array has been created, there's no cost to checking its size by calling Array#size.
A database query acts differently. Your query might have matched millions of rows, and each result might contain kilobytes of data. This is why normally you iterate over a result set instead of using select_all to get it as an array. Getting the whole result set at once might use a huge amount of memory, which is why using select_all can be disastrous.
You've got two other options. If you're going to be iterating over the entire dataset anyway,
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Talking Directly to a MySQL Database
Inhaltsvorschau
You want to send SQL queries and commands directly to a MySQL database.
Do you really need to do this? Almost all the time, it's better to use the generic DBI library. The biggest exception is when you're writing a a Rails application, and you need to run a SQL command that you can't express with ActiveRecord.
If you really want to communicate directly with MySQL, use the Ruby bindings to the MySQL client library (found in the mysql gem). It provides an interface that's pretty similar to DBI's.
Here's a MySQL-specific version of the method with_db, defined in this chapter's introduction. It returns a Mysql object, which you can use to run queries or get server information.
	require 'rubygems'

	require 'mysql'



	def with_db

	  dbh = Mysql.real_connect('localhost', 'cookbook_user', 'password',

	                           'cookbook')

	  begin

	    yield dbh

	  ensure

	    dbh.close

	  end

	end
The Mysql#query method runs any SQL statement, whether it's a SELECT query or something else. When it runs a query, the return value is a result-set object (a MysqlRes); otherwise, it's nil. Here it is running some SQL commands:
	with_db do |db|

	  db.query('drop table if exists secrets')

	  db.query('create table secrets( id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,

	                                 secret LONGTEXT )')

	  db.query(%{insert into secrets(secret) values

	     ("Oh, MySQL, you're the only one who really understands me.")})

	end
And here's a query:
	with_db do |db|

	  res = db.query('select * from secrets')

	  res.each { |row| puts "#{row[0]}: #{row[1]}" }

	  res.free

	end

	# 1: Oh, MySQL, you're the only one who really understands me.
Like the database connection itself, the result set you get from query wants to be closed when you're done with it. This calls for yet another instance of the pattern seen in with_db, in which setup and cleanup are delegated to a method that takes a code block. Here's some code that alters query to take a code block:
	class Mysql

	  alias :query_no_block :query

	  def query(sql)

	    res = query_no_block(sql)

	    return res unless block_given?

	    begin

	      yield res

	    ensure

	      res.free if res

	    end

	  end

	end
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Talking Directly to a PostgreSQL Database
Inhaltsvorschau
You want to send SQL queries and commands directly to a PostgreSQL database.
As with the MySQL recipe preceding this one, ask: do you really need to do this? The generic DBI library usually works just fine. As before, the main exception is when you need to make low-level SQL calls from within a Rails application.
There are two APIs for communicating with a PostgreSQL database, and both are available as gems. The postgres gem provides a Ruby binding to the C client library, and the postgres-pr gem provides a pure Ruby interface.
Here's a Postgres-specific version of the method with_db, defined in the chapter intro. It returns a PGconn object, which you can use to run queries or get server information. This code assumes you're accessing the database through TCP/IP on port 5432 of your local machine.
	require 'rubygems'

	require 'postgres'



	def with_db

	  db = PGconn.connect('localhost', 5432, '', '', 'cookbook',

	                      'cookbook_user', 'password')

	  begin

	    yield db

	  ensure

	    db.close

	  end

	end
The PGconn#exec method runs any SQL statement, whether it's a SELECT query or something else. When it runs a query, the return value is a result-set object (a PGresult); otherwise, it's nil. Here it is running some SQL commands:
	with_db do |db|

	  begin

	    db.exec('drop table secrets')

	  rescue PGError

	    # Unlike MySQL, Postgres does not have a "drop table unless exists"

	    # command. We can simulate it by issuing a "drop table" command and

	    # ignoring any error due to the table not existing in the first place.

	    # This is essentialy what MySQL's "drop table unless exists" does.

	  end



	  db.exec('create table secrets( id SERIAL PRIMARY KEY,

	                                 secret TEXT )')

	  db.exec(%{insert into secrets(secret) values

	            ('Oh, Postgres, you\\'re the only one who really understands me.')})

	end
Here's a query:
	with_db do |db|

	  res = db.query('select * from secrets')

	  res.each { |row| puts "#{row[0]}: #{row[1]}" }

	end

	# 1: Oh, Postgres, you're the only one who really understands me.
Note the slight differences between the Postgres implementation of SQL and the MySQL implementation. The "drop table if exists" syntax is MySQL-specific. Postgres names the data types differently, and expects string values to be single-quoted.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Using Object Relational Mapping with ActiveRecord
Inhaltsvorschau
You want to store data in a database without having to use SQL to access it.
Use the ActiveRecord library, available as the activerecord gem. It automatically defines Ruby classes that access the contents of database tables.
As an example, let's create two tables in the MySQL database cookbook (see the chapter introduction for more on creating the database itself). The blog_posts table, defined below in SQL, models a simple weblog containing a number of posts. Each blog post can have a number of comments, so we also define a comments table.
	use cookbook;



	DROP TABLE IF EXISTS blog_posts;

	CREATE TABLE blog_posts (

	  id INT(11) NOT NULL AUTO_INCREMENT,

	  title VARCHAR(200),

	  content TEXT,

	  PRIMARY KEY (id)

	) ENGINE=InnoDB;



	DROP TABLE IF EXISTS comments;

	CREATE TABLE comments (

	  id INT(11) NOT NULL AUTO_INCREMENT,

	  blog_post_id INT(11),

	  author VARCHAR(200),

	  content TEXT,

	  PRIMARY KEY (id)

	) ENGINE=InnoDB;
Here are two Ruby classes to represent those tables, and the relationship between them:
	require 'cookbook_dbconnect'

	activerecord_connect                  # See chapter introduction



	class BlogPost < ActiveRecord::Base

	  has_many :comments

	end



	class Comment < ActiveRecord::Base

	  belongs_to :blog_post

	end
Now you can create entries in the tables without writing any SQL:
	post = BlogPost.create(:title => 'First post',

	                       :content => "Here are some pictures of our iguana.")



	comment = Comment.create(:blog_post => post, :author => 'Alice',

	                         :content => "That's one cute iguana!")



	post.comments.create(:author => 'Bob', :content => 'Thank you, Alice!')
You can also query the tables, relate blog posts to their comments, and relate comments back to their blog posts:
	blog_post = BlogPost.find(:first)



	puts %{#{blog_post.comments.size} comments for "#{blog_post.title}"}

	# 2 comments for "First post"



	blog_post.comments.each do |comment|

	  puts "Comment author: #{comment.author}"

	  puts "Comment: #{comment.content}"

	end

	# Comment author: Alice

	# Comment: That's one cute iguana!

	# Comment author: Bob

	# Comment: Thank you, Alice!



	first_comment = Comment.find(:first)

	puts %{The first comment was made on "#{first_comment.blog_post.title}"}

	# The first comment was made on "First post"
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Using Object Relational Mapping with Og
Inhaltsvorschau
Credit: Mauro Cicio
You want to store data in a database, without having to use SQL to create or access the database.
Use the Og (ObjectGraph) library, available as the og gem. Where ActiveRecord has a database-centric approach to object-relational mapping, Og is Ruby-centric. With ActiveRecord, you define the database schema ahead of time and have the library figure out what the Ruby objects should look like. With Og, you define the Ruby objects and let the library take care of creating the database schema.
The only restriction Og imposes on your class definitions is that you must use special versions of the decorator methods for adding attribute accessors. For instance, instead of calling attribute to define accessor methods, you call property.
Here we define a basic schema for a weblog program, like that defined in Recipe 13.11:
	require 'cookbook_dbconnect'

	require 'og'



	class BlogPost

	  property :title, :content, String

	end



	class Comment

	  property :author, :content, String

	  belongs_to : 

og_post,  

BlogPost

	end



	# Now that Comment's been defined, add a reference to it in BlogPost.

	class BlogPost

	  has_many :comments, Comment

	end
After defining the schema, we call the og_connect method defined in the chapter introduction. Og automatically creates any necessary database tables:
	og_connect

	# Og uses the Mysql store.

	# Created table 'ogcomment'.

	# Created table 'ogblogpost'.
Now we can create a blog post and some comments:
	post = BlogPost.new

	post.title = "First post"

	post.content = "Here are some pictures of our iguana."

	post.save!



	[["Alice", "That's one cute iguana!"],

	 ["Bob", "Thank you, Alice!"]].each do |author, content|

	  comment = Comment.new

	  comment.blog_post = post

	  comment.author = author

	  comment.content = content

	  comment.save!

	end
As with ActiveRecord, we can query the tables, relate blog posts to their comments, and relate comments back to their blog posts:
	post = BlogPost.first

	puts %{#{post.comments.size} comments for "#{post.title}"}

	# 2 comments for "First post"



	post.comments.each do |comment|

	  puts "Comment author: #{comment.author}"

	  puts "Comment: #{comment.content}"

	end

	# Comment author: Alice

	# Comment: That's one cute iguana!

	# Comment author: Bob

	# Comment: Thank you, Alice!



	puts %{The first comment was made on "#{Comment.first.blog_post.title}"}

	# The first comment was made on "First post"
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Building Queries Programmatically
Inhaltsvorschau
You have to write fragments of SQL to pass parameters into an ActiveRecord query. You'd like to dispense with SQL altogether, and represent the query paramaters as a Ruby data structure.
Here's a simple solution. The method ActiveRecord::Base.find_by_map defined below picks up where find leaves off. Normally a query is represented by a SQL fragment, passed in as the :conditions argument. Here, the :conditions argument contains a mapping of database field names to the desired values:
	require 'cookbook_dbconnect'



	class ActiveRecord::Base

	  def self.find_by_map(id, args={}.freeze)

	    sql = []

	    values = []

	    args[:conditions].each do |field, value|

	      sql << "#{field} = ?"

	      values << value

	    end if args[:conditions]

	    args[:conditions] = [sql.join(' AND '), values]

	    find(id, args)

	  end

	end
Here's find_by_map in action, using the BlogPost class first seen in Recipe 13.11:
	activerecord_connect



	class BlogPost < ActiveRecord::Base

	end



	BlogPost.create(:title => 'Game Review: Foosball Carnage',

	                :content => 'Four stars!')

	BlogPost.create(:title => 'Movie Review: Foosball Carnage: The Movie',

	                :content => 'Zero stars!')



	BlogPost.find_by_map(:first,

	                     :conditions => {:title =>

	                                     'Game Review: Foosball Carnage' }

	                    ).content

	# => "Four stars!"
ActiveRecord saves you from having to write a lot of SQL, but you still have to write out the equivalent of a SQL WHERE clause every time you call ActiveRecord::Base#find. The find_by_map method lets you define those queries as Ruby hashes.
But find_by_map only lets you run one type of query: the kind where you're restricting fields of the database to specific values. What if you want to do a query that matches a field with the LIKE construct, or combine multiple clauses into a single query with AND or OR?
A hash can only represent a very simple SQL query, but the Criteria object, below, can represent almost any WHERE clause. The implementation is more complex but the idea is the same. We define a data structure that can represent the WHERE clause of a SQL query, and a way of converting the data structure into a real WHERE clause.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Validating Data with ActiveRecord
Inhaltsvorschau
You want to prevent bad data from getting into your ActiveRecord data objects, whether the source of the data is clueless users or buggy code.
The simplest way is to use the methods defined by the ActiveRecord::Validations module. Each of these methods (validates_length_of, validates_presence_of, and so on) performs one kind of validation. You can use them to declare restrictions on the data in your object's fields.
Let's add some validation code to the Comment class for the weblog application first seen in Recipe 13.11. Recall that a Comment object has two main fields: the name of the author, and the text of the comment. We'll reject any comment that leaves either field blank. We'll also reject comments that are too long, and comments whose body contains any string from a customizable list of profane words.
	require 'cookbook_dbconnect'

	activerecord_connect

	

	class Comment < ActiveRecord::Base

	  @@profanity = %w{trot krip}

	  @@no_profanity_re = Regexp.new('^(?!.*(' + @@profanity.join('|') + '))')



	  validates_presence_of %w{author}

	  validates_length_of :content, :in => 1..200

	  validates_format_of :content, :with => @@no_profanity_re,

	                      :message => 'contains profanity'

	end
Comment objects that don't fit these criteria won't be saved to the database.
	comment = Comment.create

	comment.errors.on 'author'                       # => "can't be blank"

	comment.errors['content']

	# => "is too short (minimum is 1 characters)"

	comment.save                                     # => false



	comment = Comment.create(:content => 'x' * 1000)

	comment.errors['content']

	# => "is too long (maximum is 200 characters)"



	comment = Comment.create(:author => 'Alice',

	  :content => "About what I'd expect from a trotting krip such as yourself!")

	comment.errors.count                             # => 1

	comment.errors.each_full { |msg| puts msg }

	# Content contains profanity



	comment = Comment.create(:author => 'Alice', :content => 'I disagree!')

	comment.save                                     # => true
Every ActiveRecord record has an associated
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Preventing SQL Injection Attacks
Inhaltsvorschau
You want to harden your code against SQL injection attacks, whether in DBI or ActiveRecord code.
With both ActiveRecord and DBI applications, you should create your SQL with question marks where variable interpolations should go. Pass in the variables along with the SQL to DatabaseHandle#execute, and the database will make sure the values are properly quoted.
Let's work against a simple database table tracking people's names:
	use cookbook;



	DROP TABLE IF EXISTS names;

	CREATE TABLE names (

	  first VARCHAR(200),

	  last VARCHAR(200)

	) ENGINE=InnoDB;



	INSERT INTO names values ('Leonard', 'Richardson'),

	                         ('Lucas', 'Carlson'),

	                         ('Michael', 'Loukides');
Here's a simple script that searches against that table. It's been hardened against SQL injection attacks with three techniques:
	#!/usr/bin/ruby

	# no_sql_injection.rb



	require 'cookbook_dbconnect'

	activerecord_connect

	class Name < ActiveRecord::Base; end



	print 'Enter a last name to search for: '

	search_for = readline.chomp



	# Technique 1: use ActiveRecord question marks

	conditions = ["last = ?", search_for]



	Name.find(:all, :conditions => conditions).each do |r|

	  puts %{Matched "#{r.first} #{r.last} with ActiveRecord question marks"}

	end



	# Technique 2: use ActiveRecord named variables

	conditions = ["last = :last", {:last => search_for}]

	

	Name.find(:all, :conditions => conditions).each do |r|

	  puts %{Matched "#{r.first} #{r.last}" with ActiveRecord named variables}

	end



	# Technique 3: use DBI question marks

	with_db do |db|

	  sql = 'SELECT first, last FROM names WHERE last = ?'



	  db.execute(sql, [search_for]).fetch_hash do |r|

	    puts %{Matched "#{r['first']} #{r['last']}" with DBI question marks}

	  end

	end

	

	puts "Done"
Here's how this script looks in use:
	$ ruby no_sql_injection.rb

	Enter a last name to search for: Richardson

	Matched "Leonard Richardson" with ActiveRecord question marks

	Matched "Leonard Richardson" with ActiveRecord named variables

	Matched "Leonard Richardson" with DBI question marks

	Done



	# See the Discussion if you're not sure how this attack is supposed to work.

	$ ruby no_sql_injection.rb

	Enter a last name to search for: " or 1=1

	Done
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Using Transactions in ActiveRecord
Inhaltsvorschau
You want to perform database operations as a group: if one of the operations fails, it should be as though none of them had ever happened.
Include active_record/ transactions, and you'll give each ActiveRecord class a transaction method. This method starts a database transaction, runs a code block, then commits the transaction. If the code block throws an exception, the database transaction is rolled back.
Here's some simple initialization code to give ActiveRecord access to the database tables for the weblog system first seen in Recipe 13.11:
	require 'cookbook_dbconnect'

	activerecord_connect # See chapter introduction



	class User < ActiveRecord::Base

	  has_and_belongs_to_many :blog_posts

	end



	class BlogPost < ActiveRecord::Base

	  has_and_belongs_to_many :authors, :class_name => 'User'

	end
The create_from_new_author method below creates a new entry in the users table, then associates it with a new entry in the blog_posts table. But there's a 50% chance that an exception will be thrown right after the new author is created. If that happens, the author creation is rolled back: in effect, it never happened.
	require 'active_record/ 

transactions'



	class BlogPost

	  def BlogPost.create_from_new_author(author_name, title, content)

	    transaction do

	      author = User.create(:name => author_name)

	      raise 'Random failure!' if rand(2) == 0

	      create(:authors => [author], :title => title, :content => content)

	    end

	  end

	end
Since the whole operation is enclosed within a transaction block, an exception won't leave the database in a state where the author has been created but the blog entry hasn't:
	BlogPost.create_from_new_author('Carol', 'The End Is Near',

	                                'A few more facts of doom…')

	# => #<BlogPost:0xb78b7c7c … >



	# The method succeeded; Carol's in the database:

	User.find(:first, :conditions=>"name='Carol'")

	# => #<User:0xb7888ae4 @attributes={"name"=>"Carol", … }>

	

	# Let's do another one…

	BlogPost.create_from_new_author('David', 'The End: A Rebuttal',

	                                'The end is actually quite far away…')

	# RuntimeError: Random failure!



	# The method failed; David's not in the database:

	User.find(:first, :conditions=>"name='David'")

	# => nil
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Adding Hooks to Table Events
Inhaltsvorschau
You want to run some code whenever a database row is added, updated, or deleted. For instance, you might want to send out email whenever a new blog post is created.
For Og, use the aspect-oriented features of Glue::Aspect. You can use its before and after methods to register code blocks that run before or after any Og method. The methods you're most likely to wrap are og_insert, og_update, and og_delete.
In the following code, I take the BlogPost class first defined in Recipe 13.12, and give its og_insert method an aspect that sends out email:
	require 'cookbook_dbconnect'

	require 'og'

	require 'glue/aspects'



	class BlogPost

	  property :title, :content, String

	  after :on => :og_insert do |post|

	    puts %{Sending email notification of new post "#{post.title}"}

	    # Actually send the email here…

	    end

	end



	og_connect

	post = BlogPost.new

	post.title = 'Robots are taking over'

	post.content = 'Think about it! When was the last time you saw another human?'

	post.save!

	# Sending email notification of new post "Robots are taking over"
This technique works with ActiveRecord as well (since aspect-oriented programming is a generic technique), but ActiveRecord defines two different approaches: callbacks and the ActiveRecord::Observer class.
Any ActiveRecord::Base subclass can define a number of callback methods: before_find, after_save, and so on. These methods run before or after the corresponding ActiveRecord methods. Here's an callback-based ActiveRecord implementation of the Og example, running against the blog_post table first defined in Recipe 13.11. If you ran the previous example in a session, quit it now and start a new session.
	require 'cookbook_dbconnect'

	activerecord_connect



	class BlogPost < ActiveRecord::Base

	  def after_create

	    puts %{Sending email notification of new blog post "#{title}"}

	    # Actually send the email here…

	  end

	end



	post = BlogPost.create(:title => 'Robots: Gentle Yet Misunderstood',

	                       :content => 'Popular misconceptions about robERROR 40')

	# Sending email notification of new blog post "Robots: Gentle Yet Misunderstood
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Adding Taggability with a Database Mixin
Inhaltsvorschau
Without writing a lot of code, you want to make one of your database tables " taggable"—make it possible to add short strings describing a particular item in the table.
Og comes complete with a tagging mixin. Just call is Taggable on every class you want to be taggable. Og will create all the necessary tables.
Here's the BlogPost class from Recipe 13.12, only this time it's Taggable. Og automatically creates a Tag class and the necessary database tables:
	require 'cookbook_dbconnect'

	require 'og'

	require 'glue/taggable'



	class BlogPost

	  is Taggable

	  property :title, :content, String

	end

	og_connect



	# Now we can play around with tags.

	post = BlogPost.new

	post.title = 'Some more facts about video games'

	post.tag(['editorial', 'games'])

	

	BlogPost.find_with_tags('games').each { |puts| puts post.title }

	# Some more facts about video games



	Tag.find_by_name('editorial').blog_posts.each { |post| puts post.title }

	# Some more facts about video games
To get this feature in ActiveRecord, you'll need to install the acts_as_taggable gem, and you must create the database tables yourself. Here are the tables necessary to add tags to the ActiveRecord BlogPost class (first described in Recipe 13.11): a generic tags table and a join table connecting it to blog_posts.
	DROP TABLE IF EXISTS tags;

	CREATE TABLE tags (

	  id INT(11) NOT NULL AUTO_INCREMENT,

	  name VARCHAR(32),

	  PRIMARY KEY (id)

	) ENGINE=InnoDB;



	DROP TABLE IF EXISTS tags_blog_posts;

	CREATE TABLE tags_blog_posts (

	   tag_id INT(11),

	   blog_post_id INT(11)

	) ENGINE=InnoDB;
Note that the join table violates the normal ActiveRecord naming rule. It's called tags_blog_posts, even though alphabetical ordering of its component tables would make it blog_posts_tags. ActiveRecord does this so all of your application's tags_join tables will show up together in a sorted list. If you want to call the table blog_posts_tags instead, you'll need to pass the name as the :join_table parameter when you call the acts_as_ taggable decorator below.
Here's the ActiveRecord code that makes BlogPost
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Chapter 14: Internet Services
Inhaltsvorschau
Network programming is hard. The C socket library is the standard way of writing Internet clients and servers. It's like the file API descibed in Chapter 6, with its special flags and meager abstraction, only much more complicated. It's a shame because networked applications are the coolest kind of application. Only computer nerds like you and me care about XML or the best way to sort a list, but everyone uses Internet applications.
Fortunately, network programming is easy. Ruby provides bindings to the C socket library (in socket), but you'll probably never need to use them. Existing Ruby libraries (some in the standard distribution) can speak every popular high-level Internet protocol.
The most popular Internet service is, of course, the Web, and Ruby's most popular Internet library (or any kind of library, actually) is the Rails framework. We've devoted the entire next chapter to Rails (Chapter 15) so that we can cover other technologies here.
Apart from Rails, most of the interesting stuff you can do with Ruby happens on the client end. We start with a set of recipes for requesting web pages (Recipes 14.1, 14.2, and 14.3), which are brought together at the end of the chapter with Recipe 14.20. Combine these recipes with one from Chapter 11 (probably Recipe 11.5), and you can make your own spider or web browser.
Then we present Ruby clients for the most popular Internet protocols. Ruby can do just about everything you do online: send and receive email, perform nameserver queries, even transfer files with FTP, SCP, or BitTorrent. With the Ruby interfaces, you can write custom clients for these protocols, or integrate them into larger programs.
It's less likely that you'll be writing your own server in Ruby. A server only exists to service clients, so there's not much you can do but faithfully implement the appropriate protocol. If you do write a server, it'll probably be for a custom protocol, one for which no other server exists.
Ruby provides two basic servers that you can use as a starting point. The gserver library described in Recipe 14.14 provides a generic framework for almost any kind of Internet server. Here you do have to do some socket programming, but only the easy parts.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Grabbing the Contents of a Web Page
Inhaltsvorschau
You want to display or process a specific web page.
The simplest solution is to use the open-uri library. It lets you open a web page as though it were a file. This code fetches the oreilly.com homepage and prints out the first part of it:
	require ' 

open-uri'

	puts open('http://www.oreilly.com/').read(200)

	# <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

	#         "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

	# <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
For more complex applications, you'll need to use the net/http library. Use Net::HTTP.get_response to make an HTTP request and get the response as a Net::HTTPResponse object containing the response code, headers, and body.
	require ' 

net/http'

	response = Net::HTTP.get_response('www.oreilly.com', '/about/')

	response.code                                             # => "200"

	response.body.size                                        # => 21835

	response['Content-type']

	# => "text/html; charset=ISO-8859-1"

	puts response.body[0,200]

	# <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

	#    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

	#

	#

	# <html>

	# <head>

	# <meta http-equiv="content-type" content="text/html; c
Rather than passing in the hostname, port, and path as separate arguments, it's usually easier to create URI objects from URL strings and pass those into the Net::HTTP methods.
	require 'uri'

	Net::HTTP.get(URI.parse("http://www.oreilly.com"))

	Net::HTTP.get_response(URI.parse("http://www.oreilly.com/about/"))
If you just want the text of the page, use get. If you also want the response code or the values of the HTTP response headers, use get_reponse.
The get_response method returns some HTTPResponse subclass of Net:HTTPResponse, which contains all information about an HTTP response. There's one subclass for every response code defined in the HTTP standard; for instance, HTTPOK for the 200 response code, HTTPMovedPermanently for the 301 response code, and HTTPNotFound for the 404 response code. There's also an
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Making an HTTPS Web Request
Inhaltsvorschau
You want to connect to an HTTPS web site, one whose traffic is encrypted using SSL.
You need the OpenSSL extension to Ruby. You'll know if it's installed if you can require the net/https library without getting a LoadError.
	require 'net/https'                       # => true
You can't make HTTPS requests with the convenience methods described in Recipe 14.1, but you can use the Net::HTTP::Get and Net::HTTP::Post class described in Recipe 14.3. To make an HTTPS request, just instantiate a Net::HTTP object and set its use_ssl member to true.
In this example, I try to download a page from a web server that only accepts HTTPS connections. Instead of listening on port 80 like a normal web server, this server listens on port 443 and expects an encrypted request. I can only connect with a Net::HTTP instance that has the use_ssl flag set.
	require 'net/http'

	uri = URI.parse("https://www.donotcall.gov/")



	request = Net::HTTP.new(uri.host, uri.port)

	response = request.get("/")

	# Errno::ECONNRESET: Connection reset by peer



	require 'net/https'

	request.use_ssl = true

	request.verify_mode = OpenSSL::SSL::VERIFY_NONE

	response = request.get("/")

	# => #<Net::HTTPOK 200 OK readbody=true>

	response.body.size                              # => 6537
The default Ruby installation for Windows includes the OpenSSL extension, but if you're on a Unix system, you might have to install it yourself. On Debian GNU/Linux, the package name is libopenssl-ruby[Ruby version]: for instance, libopenssl-ruby1.8. You might need to download the extension from the Ruby PKI homepage (see below), and compile and install it with Make.
Setting verify_mode to OpenSSL:SSL::VERIFY_NONE suppresses some warnings, but the warnings are kind of serious: they mean that OpenSSL won't verify the server's certificate or proof of identity. Your conversation with the server will be confidential, but you won't be able to definitively authenticate the server: it might be an imposter.
You can have OpenSSL verify server certificates if you keep a few trusted certificates on your computer. You don't need a certificate for every server you might possibly access. You just need certificates for a few "certificate authorities:" the organizations that actually sign most other certificates. Since web browsers need these certificates too, you probably already have a bunch of them installed, although maybe not in a format that Ruby can use (if you don't have them, see below).
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Customizing HTTP Request Headers
Inhaltsvorschau
When you make an HTTP request, you want to specify custom HTTP headers like " User-Agent" or " Accept-Language".
Pass in a Hash of header values to Net::HTTP#get or Net::HTTP#post:
	require 'net/http'

	require 'uri'



	#A simple wrapper method that accepts either strings or URI objects

	#and performs an HTTP GET.

	module Net

	  class HTTP

	    def HTTP.get_with_headers(uri, headers=nil)

	      uri = URI.parse(uri) if uri.respond_to? :to_str

	      start(uri.host, uri.port) do | 

http|

	        return  

http.get(uri.path, headers)

	      end

	    end

	  end

	end



	#Let's get a web page in German.

	res = Net::HTTP.get_with_headers('http://www.google.com/',

	                                 {' 

Accept-Language' => 'de'})



	#Check a bit of the body to make sure it's really in German.

	s = res.body.size

	res.body[s-200..s-140]

	# => "ngebote</a> - <a href=/intl/de/about.html>Alles \374ber Google</"
Usually you can retrieve the web pages you want without specifying any custom HTTP headers. As you start performing more complicated interactions with web servers, you'll find yourself customizing the headers more.
For instance, if you write a web spider or client, you'll want it to send a " User-Agent" header on every request, identifying itself to the web server. Unlike the HTTP client libraries for other programming languages, the net/http library doesn't send a "User-Agent" header by default; it's your reponsibility to send one.
	Net::HTTP.get_with_headers(url, {'User-Agent' => 'Ruby Web Browser v1.0'})
You can often save bandwidth (at the expense of computer time) by sending an "Accept-Encoding" header, requesting that a web server compress data before sending it to you. Gzip compression is the most common way a server compresses HTTP response data; you can reverse it with Ruby's zlib library:
	uncompressed = Net::HTTP.get_with_headers('http://www.cnn.com/')

	uncompressed.body.size

	# => 65150



	gzipped = Net::HTTP.get_with_headers('http://www.cnn.com/',

	                                     {'Accept-Encoding' => 'gzip'})

	gzipped['Content-Encoding']

	# => "gzip"

	gzipped.body.size

	# => 14600



	require 'zlib'

	require 'stringio'

	body_io = StringIO.new(gzipped.body)

	unzipped_body = Zlib::GzipReader.new(body_io).read()

	unzipped_body.size

	# => 65150
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Performing DNS Queries
Inhaltsvorschau
You want to find the IP address corresponding to a domain name, or see whether a domain provides a certain service (such as an email server).
Use the Resolv:: DNS class in the standard resolv library to perform DNS lookups. The most commonly used method is DNS#each_address, which iterates over the IP addresses assigned to a domain name.
	require 'resolv' 

Resolv::DNS.new.each_address("oreilly.com") { |addr| puts addr }

	# 208.201.239.36

	# 208.201.239.37
If you need to check the existence of a particular type of DNS record (such as a MX record for a mail server), use DNS#getresources or the iterator DNS#each_resource. Both methods take a domain name and a class denoting a type of DNS record. They perform a DNS lookup and, for each matching DNS record, return an instance of the given class.
These are the three most common classes:
DNS::Resource::IN::A
Indicates a DNS record pointing to an IP address for the domain.
DNS::RESOURCE::IN::NS
Indicates a DNS record pointing to a DNS nameserver.
DNS::Resource::IN::MX
Indicates a DNS record pointing to a mail server.
This code finds the mail servers and name servers responsible for oreilly.com:
	dns = 

Resolv::DNS.new

	domain = "oreilly.com"

	dns.each_resource(domain, Resolv::DNS::Resource::IN::MX) do |mail_server|

	  puts mail_server.exchange

	end

	# smtp1.oreilly.com

	# smtp2.oreilly.com



	dns.each_resource(domain, Resolv::DNS::Resource::IN::NS) do |nameserver|

	  puts nameserver.name

	end

	# a.auth-ns.sonic.net

	# b.auth-ns.sonic.net

	# c.auth-ns.sonic.net

	# ns.oreilly.com
If your application needs to do a lot of DNS lookups, you can greatly speed things up by creating a separate thread for each lookup. Most of the time spent doing a DNS lookup is spent connecting to the network, so doing all the lookups in parallel can save a lot of time. If you do this, you should include the resolv-replace library along with resolv, to make sure your DNS lookups are thread-safe.
Here's some code that sees which one-letter
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Sending Mail
Inhaltsvorschau
You want to send an email message, either an autogenerated one or one entered in by an end user.
First you need to turn the parts of the email message into a single string, representing the whole message complete with headers and/or attachments. You can construct the string manually or use a number of libraries, including RubyMail, TMail, and ActionMailer. Since ActionMailer is one of the dependencies of Rails, I'll use it throughout this recipe. ActionMailer uses TMail under the covers, and it's provided by the actionmailer gem.
Here, I use ActionMailer to construct a simple, single-part email message:
	require 'rubygems'

	require 'action_mailer'



	class SimpleMailer < ActionMailer::Base

	  def simple_message(recipient)

	     from 'leonardr@example.org'

	     recipients recipient

	     subject 'A single-part message for you'

	     body 'This message has a plain text body.'

	   end

	end
ActionMailer then makes two new methods available for generating this kind of email message: SimpleMailer. create_simple_message, which returns the email message as a data structure, and SimpleMailer. deliver_simple_message, which actually sends the message.
	puts SimpleMailer. 

create_simple_message('lucas@example.com')

	# From: leonardr@example.org

	# To: lucas@example.com

	# Subject: A single-part message for you

	# Content-Type: text/plain; charset=utf-8

	#

	# This message has a plain text body.
To deliver the message, call deliver_simple_message instead of create_simple_message. First, though, you'll need to tell ActionMailer about your SMTP server. If you're sending mail from example.org and you've got an SMTP server on the local machine, you might send a message this way:
	ActionMailer::Base.server_settings = { :address => 'localhost',

	                                       :port => 25, # 25 is the default

	                                       :domain => 'example.org' }



	SimpleMailer.deliver_simple_message('lucas@example.com')
If you're using your ISP's SMTP server, you'll probably need to send authentication information so the server knows you're not a spammer. Your ActionMailer setup will probably look like this:
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Reading Mail with IMAP
Inhaltsvorschau
Credit: John Wells
You want to connect to an IMAP server in order to read and manipulate the messages stored there.
The net/imap.rb package, written by Shugo Maeda, is part of Ruby's standard library, and provides a very capable base on which to build an IMAP-oriented email application. In the following sections, I'll walk you through various ways of using this API to interact with an IMAP server.
For this recipe, let's assume you have access to an IMAP server running at mail.myhost.com on the standard IMAP port 143. Your username is, conveniently, "username", and your password is "password".
To make the initial connection to the server, it's as simple as:
	require 'net/imap'



	conn = Net::IMAP.new('mail.myhost.com', 143)

	conn.login('username', 'password')
Assuming no error messages were received, you now have a connection to the IMAP server. The Net::IMAP object puts all the capabilities of IMAP at your fingertips.
Before doing anything, though, you must tell the server which mailbox you're interested in working with. On most IMAP servers, your default mailbox is called "INBOX". You can change mailboxes with Net::IMAP#examine:
	conn.examine('INBOX')

	# Use Net::IMAP#select instead for read-only access
A search provides a good example of how a Net::IMAP object lets you interact with the server. To search for all messages in the selected mailbox from a particular address, you can use this code:
	conn.search(['FROM', 'jabba@huttfoundation.org']).each do |sequence|

	    fetch_result = conn.fetch(sequence, 'ENVELOPE')

	    envelope = fetch_result[0].attr['ENVELOPE']

	    printf("%s - From: %s - To: %s - Subject: %s\n", envelope.date,

	         envelope.from[0].name, envelope.to[0].name, envelope.subject)

	end

	# Wed Feb 08 14:07:21 EST 2006 - From: The Hutt Foundation - To: You - Subject: Bwah!

	# Wed Feb 08 11:21:19 EST 2006 - From: The Hutt Foundation - To: You - Subject: Go to

	# do wa IMAP
The details of the IMAP protocol are a bit esoteric, and to really understand it you'll need to read the RFC. That said, the code in the solution shouldn't be too hard to understand: it uses the IMAP
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Reading Mail with POP3
Inhaltsvorschau
Credit: John Wells
You want to connect to an POP server in order to read and download the messages stored there.
The net/pop.rb package, written by Minero Aoki, is part of Ruby's standard library, and provides a foundation on which to build a POP (Post Office Protocol)-oriented email application. As with the previous recipe on IMAP, we'll walk through some common ways of accessing a mail server with the POP API.
For this recipe, we assume you have access to a POP3 server running at mail.myhost. com on the standard POP3 port 110. Just as in the previous IMAP example, your username is "username", and password is (yep) "password".
To make the initial connection to the server, it's as simple as:
	require 'net/pop'



	conn = Net::POP3.new('mail.myhost.com')

	conn.start('username', 'password')
If you receive no errors, you've got an open session to your POP3 server, and can use the conn object to communicate with the server.
The following code acts like a typical POP3 client: having connected to the server, it downloads all the new messages, and then deletes them from the server. The deletion is commented out so you don't lose mail accidentally while testing this code:
	require 'net/pop'



	conn = Net::POP3.new('mail.myhost.com')

	conn.start('username', 'password')



	conn.mails.each do |msg|

	   File.open(msg.uidl, 'w') { |f| f.write msg.pop }

	   # msg.delete

	end



	conn.finish
POP3 is a much simpler protocol than IMAP, and arguably a less powerful one. It doesn't support the concept of folders, so there's no need to start off by selecting a particular folder (like we did in the IMAP recipe). Once you start a session, you have immediate access to all messages currently retained on the server.
IMAP stores your folders and your messages on the server itself. This way you can access the same messages and the same folders from different clients on different machines. For example, you might go to work and access an IMAP folder with Mozilla Thunderbird, then go home and access the same folder with a web-based mail client.
With POP3, there are no server-side folders. You're supposed to archive your messages on the client side. If you use a POP3 client to download messages at work, when you get home you won't be able to access those messages. They're on your work computer, not on the POP3 server.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Being an FTP Client
Inhaltsvorschau
You want to automatically connect to an FTP server, and upload or download files.
Use the Net::FTP class. It provides a filesystem-like interface to an FTP server. In this example, I log anonymously into a popular FTP site, browse one of its directories, and download two of its files:
	require 'net/ftp'

	ftp = 

Net::FTP.open('ftp.ibiblio.org') do |ftp|

	  ftp.login

	  ftp.chdir('pub/linux/')

	  ftp.list('*Linux*') { |file| puts file }

	  puts



	  puts 'Saving a text file to disk while processing it.'

	  ftp.gettextfile('How-do-I-get-Linux') { |line| puts "! #{line}" }

	  puts "Saved #{File.size 'How-do-I-get-Linux'} bytes."

	  puts



	  puts 'Saving a binary file to disk.'

	  ftp.getbinaryfile('INDEX.whole.gz')

	 puts "Saved #{File.size 'INDEX.whole.gz'} bytes."

	end

	# -rw-r--r--   1 (?)      users    16979001 Jan 1 11:31 00-find.Linux.gz

	# -rw-rw-r--   1 (?)      admin          73 Mar 9  2001 How-do-I-get-Linux



	# Saving a text file to disk while processing it.

	# !

	# !   Browse to http://metalab.unc.edu/linux/HOWTO/Installation-HOWTO.html

	# !

	# Saved 73 bytes.



	# Saving a binary file to disk.

	# Saved 213507 bytes.
Once the preferred way of storing and serving files through the Internet, FTP is being largely superceded by SCP for copying files, the web for distributing files, and Bit-Torrent for distributing very large files. There are still many anonymous FTP servers, though, and many web hosting companies still expect you to upload your web pages through FTP.
The login method logs in to the server. Calling it without arguments logs you in anonymously, which traditionally limits you to download privileges. Calling it with a username and password logs you in to the server:
	ftp.login('leonardr', 'mypass')
The methods chdir and list let you navigate the FTP server's directory structure. They work more or less like the Unix cd and ls commands (in fact, list is aliased to ls and dir).
There are also two "get" methods and two "put" methods. The "get" methods are getbinaryfile and gettextfile. They retrieve the named file from the FTP server and write it to disk. The
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Being a Telnet Client
Inhaltsvorschau
You want to connect to a telnet service or use telnet to get low-level access to some other kind of server.
Use the Net::Telnet module in the Ruby standard library.
The following code uses a Telnet object to simulate an HTTP client. It sends a raw HTTP request to the web server at http://www.oreilly.com. Every chunk of data received from the web server is passed into a code block, and its size is added to a tally. Eventually the web server stops sending data, and the telnet session times out.
	require 'net/telnet'



	webserver = Net::Telnet::new('Host' => 'www.oreilly.com',

	                             'Port' => 80,

	                             'Telnetmode' => false)



	size = 0

	webserver.cmd("GET / HTTP/1.1\nHost: www.oreilly.com\n") do |c|

	  size += c.size

	  puts "Read #{c.size} bytes; total #{size}"

	end

	# Read 1431 bytes; total 1431

	# Read 1434 bytes; total 2865

	# Read 1441 bytes; total 4306

	# Read 1436 bytes; total 5742

	# …

	# Read 1430 bytes; total 39901

	# Read 2856 bytes; total 42757

	# /usr/lib/ruby/1.8/net/telnet.rb:551:in 'waitfor':

	#   timed out while waiting for more data (Timeout::Error)
Telnet is a lightweight protocol devised for connecting to a generic service running on another computer. For a long time, the most commonly exposed service was a Unix shell: you would "telnet in" to a machine on the network, log in, and run shell commands on the other machine as though it were local.
Because telnet is an insecure protocol, it's very rare now to use it for remote login. Everyone uses SSH for that instead (see the next recipe). Telnet is still useful for two things:
  1. As a diagnostic tool (as seen in the Solution). Telnet is very close to being a generic TCP protocol. If you know, say, HTTP, you can connect to an HTTP server with telnet, send it a raw HTTP request, and view the raw HTTP response.
  2. As a client to text-based services other than remote shells: mainly old-school entertainments like BBSes and MUDs.
Telnet objects implement a simple loop between you and some TCP server:
  1. You send a string to the server.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Being an SSH Client
Inhaltsvorschau
You want to securely send data or commands back and forth between your computer, and another computer on which you have a shell account.
Use the Net::SSH module, which implements the SSH2 protocol. It's found in the net-ssh gem, although some operating systems package it themselves. It lets you implement Ruby applications that work like the familiar ssh and scp.
You can start an SSH session by passing a hostname to Net::SSH::start, along with your shell username and password on that host. If you have an SSH public/private key pair set up between your computer and the remote host, you can omit the username and password:
	require 'rubygems'

	require 'net/ssh' 

Net::SSH.start('example.com', :username=>'leonardr',

	               :password=>'mypass') do |session|

	  # Manipulate your Net::SSH::Session object here…

	end
Net::SSH::start takes a code block, to which it passes a Net::SSH::Session object. You use the session object to send encrypted data between the machines, or to spawn processes on the remote machine. When the code block ends, the SSH session is automatically terminated.
It seems strange now, but until the late 1990s, people routinely used unsecured protocols like telnet to get shell access to remote machines. Remote access was so useful that we were willing to jeopardize our electronic safety by sending our shell passwords (not to mention all the data we looked at) unencrypted across the network. Fortunately, we don't have to make that trade-off anymore. The SSH protocol makes it easy to send encrypted traffic between machines, and the client tools ssh and scp have almost completely replaced tools like RSH and nonanonymous FTP.
The Net::SSH library provides a low-level interface to the SSH2 protocol, but most of the time you won't need it. Instead, you'll use one of the abstractions that make it easy to spawn and control processes on a remote machine. The simplest abstraction is the popen3 method, which works like the local popen3 method in Ruby's open3 library. It's covered in more detail in Recipe 20.10, but here's a simple example:
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Copying a File to Another Machine
Inhaltsvorschau
You want to programatically send files to another computer, the way the Unix scp command does.
Use the Net:SSH library to get a secure shell connection to the other machine. Start a cat process on the other machine, and write the file you want to copy to its standard input.
	require 'rubygems'

	require 'net/ssh'



	def copy_file(session, source_path, destination_path=nil)

	  destination_path ||= source_path

	  cmd = %{cat > "#{destination_path.gsub('"', '\"')}"}

	  session.process.popen3(cmd) do |i, o, e|

	    puts " 

Copying #{source_path} to #{destination_path}… "

	    open(source_path) { |f| i.write(f.read) }

	    puts 'Done.'

	  end

	end



	Net::SSH.start('example.com', :username=>'leonardr',

	               :password=>'mypass') do |session|

	  copy_file(session, '/home/leonardr/scripts/test.rb')

	  copy_file(session, '/home/leonardr/scripts/"test".rb')

	end

	# Copying /home/leonardr/scripts/test.rb to /home/leonardr/scripts/test.rb…

	# Done.

	# Copying /home/leonardr/scripts/"test".rb to /home/leonardr/scripts/"test".rb…

	# Done.
The scp command basically implements the old rcp protocol over a secured connection. This code uses a shortcut to achieve the same result: it uses the high-level SSH interface to spawn a process on the remote host which writes data to a file.
Since you can run multiple processes at once over your SSH session, you can copy multiple files simultaneously. For every file you want to copy, you need to spawn a cat process:
	def do_copy(session, source_path, destination_path=nil)

	  destination_path ||= source_path

	  cmd = %{cat > "#{destination_path.gsub('"', '\"')}"}

	  cat_process = session.process.open(cmd)



	  cat_process.on_success do |p|

	    p.write(open(source_path) { |f| f.read })

	    p.close

	    puts "Copied #{source_path} to #{destination_path}."

	  end

	end
The call to session.process.open creates a process-like object that runs a cat command on the remote system. The call to on_success registers a callback code block with the process. That code block will run once the cat command has been set up and is accepting standard input. Once that happens, it's safe to start writing data to the file on the remote system.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Being a BitTorrent Client
Inhaltsvorschau
You want to write a Ruby script that downloads or shares large files with BitTorrent.
The third-party RubyTorrent library implements the BitTorrent protocol; you can use it to write BitTorrent clients. The RubyTorrent package has no setup.rb file, so you'll need to manually copy the files into your Ruby classpath or package them with your application.
The BitTorrent class acts as a BitTorrent client, so to download a torrent, all you have to do is give it the path or URL to a .torrent file. This code will download the classic B-movie Night of the Living Dead to the current working directory:
	require 'rubytorrent'

	file = 'http://publicdomaintorrents.com/bt/btdownload.php?type=torrent' +

	        '&file=Night_of_the_Living_Dead.avi.torrent'

	client = RubyTorrent::BitTorrent.new(file)
Run this in irb, keep your session open, and in a few hours (or days), you'll have your movie!
BitTorrent is the most efficient way yet devised for sharing large files between lots of people. As you download the file you're also sharing what you've downloaded with others: the more people are trying to download the file, the faster it is for everyone.
RubyTorrent is a simple client library to the BitTorrent protocol. In its simplest form, you simply construct a BitTorrent object with the URL or path to a torrent information file, and wait for the download to complete. However, there's a lot more you can do to provide a better user interface.
The BitTorrent object has several methods that let you keep track of the progress of the download:
	client.num_active_peers                     # => 9

	# That is, 9 other people are downloading this file along with me.



	client.ulrate                               # => 517.638825414351

	client.dlrate                               # => 17532.608916979

	# That is, about 3 kb/sec uploading and 17 kb/sec downloading.



	client.percent_completed                    # => 0.25
You can also register code blocks to be run at certain points in the client's lifecycle. Here's a more advanced BitTorrent client that registers code blocks to let the user know about new and dropped peer connections. It also uses a thread to occasionally report on the progress of the download. The user can specify which port to use when uploading data to peers, and a maximum upload rate in kilobytes.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Pinging a Machine
Inhaltsvorschau
You want to check whether a particular machine or domain name can be reached from your computer.
Use Ruby's standard ping library. Its single method, Ping.pingecho, tries to get some machine on the network to respond to its entreaties. It takes either a domain name or an IP address, and returns true if it gets a response.
	require 'ping' 

ping.pingecho('oreilly.com') 	                         # => true



	# timeout of 10 seconds instead of the default 5 seconds

	Ping.pingecho('127.0.0.1', 10)                           # => true

	#  

ping port 80 instead of the default echo port

	 

Ping.pingecho('slashdot.org', 5, 80)                     # => true



	 

Ping.pingecho('no.such.domain')                          # => false

	 

Ping.pingecho('222.222.222.222')                         # => false
Ping.pingecho performs a TCP echo: it tries to make a TCP connection to the given machine, and if the machine responds (even if to refuse the connection) it means the machine was reachable.
This is not the ICMP echo of the Unix ping command, but the difference almost never matters. If you absolutely need an ICMP echo, you can invoke ping with a system call and check the return value:
	system('ping -c1 www.oreilly.com')

	# 64 bytes from 208.201.239.36: icmp_seq=0 ttl=42 time=27.2 ms

	#

	# --- www.oreilly.com ping statistics --

	# 1 packets transmitted, 1 packets received, 0% packet loss

	# round-trip min/avg/max = 27.2/27.2/27.2 ms

	# => true
If the domain has a DNS entry but can't be reached, Ping::pingecho may raise a Timeout::Error instead of returning false.
Some very popular or very paranoid domains, such as microsoft.com, don't respond to incoming ping requests. However, you can usually access the web server or some other service on the domain. You can see whether such a domain is reachable by using one of Ruby's other libraries:
	ping.pingecho('microsoft.com')                          # => false



	require 'net/http'

	Net::HTTP.start('microsoft.com') { 'success!' }         # => "success!"

	Net::HTTP.start('no.such.domain') { "success!" }

	# SocketError: getaddrinfo: Name or service not known
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Writing an Internet Server
Inhaltsvorschau
You want to run a server for a TCP/IP application-level protocol, but no one has written a Ruby server for the protocol yet. This may be because it's a protocol you've made up.
Use the gserver library in Ruby's standard library. It implements a generic TCP/IP server suitable for small to medium-sized tasks.
Here's a very simple chat server written with gserver. It has no end-user features to speak of. People connect to the server with a telnet client, and are identified to each other only by hostname. But it's a fully functional, multithreaded, logging server written in about 30 lines of Ruby.
	#!/usr/bin/ruby -w

	# chat.rb

	require ' 

gserver'



	class ChatServer < GServer



	  def initialize(port=20606, host=GServer::DEFAULT_HOST)

	    @clients = []

	    super(port, host, Float::MAX, $stderr, true)

	  end



	  def serve(sock)

	    begin

	      @clients << sock

	      hostname = sock.peeraddr[2] || sock.peeraddr[3]

	      @clients.each do |c|

	        c.puts "#{hostname} has joined the chat." unless c == sock

	      end

	      until sock.eof? do

	        message = sock.gets.chomp

	        break if message == "/quit"

	        @clients.each { |c| c.puts "#{hostname}: #{message}" unless c == sock }

	      end

	    ensure

	      @clients.delete(sock)

	      @clients.each { |c| c.puts "#{hostname} has left the chat." }

	    end

	  end

	end



	server = ChatServer.new(*ARGV[0..2] || 20606)

	server.start(-1)

	server.join
Start the server in a Ruby session, and then use several instances of the telnet program to connect to port 20606 (from several different hosts, if you can). Your telnet sessions will be able to communicate with each other through the server. Your Ruby session will see a log of the connections and disconnections.
The GServer class wraps Ruby's underlying TCPServer class in a loop that continually receives TCP connections and spawns new threads to process them. Each new thread passes its TCP connection (a TCPSocket object) into the GServer#serve method, which your subclass is responsible for providing.
The TCPSocket works like a bidirectional file. Writing to it pushes data to the client, and reading from it reads data from the client. A server like the sample chat server reads one line at a time from the client; a web server would read the entire request before sending back any data.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Parsing URLs
Inhaltsvorschau
You want to parse a string representation of a URL into a data structure that articulates the parts of the URL.
URI.parse transforms a string describing a URL into a URI object. The parts of the URL can be determined by interrogating the URI object.
	require 'uri'



	URI.parse('https://www.example.com').scheme           # => "https"

	URI.parse('http://www.example.com/').host             # => "www.example.com"

	URI.parse('http://www.example.com:6060/').port        # => 6060

	URI.parse('http://example.com/a/file.html').path      # => "/a/file.html"
URI.split transforms a string into an array of URL parts. This is more efficient than URI.parse, but you have to know which parts correspond to which slots in the array:
	URI.split('http://example.com/a/file.html')

	# => ["http", nil, "example.com", nil, nil, "/a/file.html", nil, nil, nil]
The URI module contains classes for five of the most popular URI schemas. Each one can store in a structured format the data that makes up a URI for that schema. URI.parse creates an instance of the appropriate class for a particular URL's scheme.
Every URI can be decomposed into a set of components, joined by constant strings. For example: the components for a HTTP URI are the scheme ("http"), the hostname ("www.example.com (http://www.example.com)"), and so on. Each URI schema has its own components, and each of Ruby's URI classes stores the names of its components in an ordered array of symbols, called component:
	URI::HTTP.component

	# => [:scheme, :userinfo, :host, :port, :path, :query, :fragment]



	URI::MailTo.component

	# => [:scheme, :to, :headers]
Each of the components of a URI class has a corresponding accessor method, which you can call to get one component of a URI. You can also instantiate a URI class directly (rather than going through URI.parse) by passing in the appropriate component symbols as a map of keyword arguments.
	URI::HTTP.build(:host => 'example.com', :path => '/a/file.html',

	                :fragment => 'section_3').to_s

	# => "http://example.com/a/file.html#section_3"
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Writing a CGI Script
Inhaltsvorschau
Credit: Chetan Patil
You want to expose Ruby code through an existing web server, without having to do any special configuration.
Most web servers are set up to run CGI scripts, and it's easy to write CGI scripts in Ruby. Here's a simple CGI script that calls the Unix command ps, parses its results, and outputs the list of running processes as an HTML document. Anyone with access to the web server can then look at the processes running on the system.
	#!/usr/bin/ruby

	# ps.cgi



	processes = %x{ps aux}.collect do |proc|

	  '<tr><td>' + proc.split(/\s+/, 11).join('</td><td>') + '</td></tr>'

	end



	puts 'Content-Type: text/html'

	# Output other HTTP headers here…

	puts "\n"



	title = %{Processes running on #{ENV['SERVER_NAME'] || `hostname`.strip}}

	puts <<-end

	  <HTML>

	   <HEAD><TITLE>#{title}</TITLE></HEAD>

	   <BODY>

	   <H1>#{title}</H1>

	   <TABLE>

	    #{processes.join("\n")}

	  </TABLE>

	  </BODY>

	  </HTML>

	end



	exit 0
CGI was the first major technology to add dynamic elements to the previously static Web. A CGI resource is requested like any static HTML document, but behind the scenes the web server executes an external program (in this case, a Ruby script) instead of serving a file. The output of the program—text, HTML, or binary data—is sent as part of the HTTP response to the browser.
CGI has a very simple interface, based on environment variables and standard input and output; one that should be very familiar to writers of command-line programs. This simplicity is CGI's weakness: it leaves too many things undefined. But when a Rails application would be overkill, a CGI script might be the right size.
CGI programs typically reside in a special directory of the web server's web space (often the /cgi-bin directory). On Unix systems, CGI files must be made executable by the web server, and the first line of the script must point to the system's Ruby interpreter (usually /usr/bin/ruby or /usr/local/bin/ruby).
A CGI script gets most of its input from environment variables like QUERY_STRING and PATH_INFO, which are set by the web server. The web server also uses environment variables to tell the script where and how it's being run: note how the sample script uses
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Setting Cookies and Other HTTP Response Headers
Inhaltsvorschau
Credit: Mauro Cicio
You're writing a CGI program and you want to customize the HTTP headers you send in response to a request. For instance, you may want to set a client-side cookie so that you can track state between HTTP requests.
Pass a hash of headers into the CGI#out method that creates the HTTP response. Each key of the hash is the name of a header to set, or a special value (like cookie), which the CGI class knows how to interpret.
Here's a CGI script that demonstrates how to set some response headers, including a cookie and a custom HTTP header called "Recipe Name".
First we process any incoming cookie. Every time you hit this CGI, the value stored in your cookie will be incremented, and the date of your last visit will be reset.
	#!/usr/bin/ruby

	# headers.cgi



	require "cgi"

	cgi = CGI.new("html3")



	# Retrieve or create the "rubycookbook" cookie

	cookie = cgi. 

cookies['rubycookbook']

	cookie = CGI::Cookie.new('rubycookbook', 'hits=0',

	                         "last=#{Time.now}") if cookie.empty?



	# Read the values in the cookie for future use

	hits = cookie.value[0].split('=')[1]

	last = cookie.value[1].split('=')[1]



	# Set new values in the cookie

	cookie.value[0] = "hits=#{hits.succ}"

	cookie.value[1] = "last=#{Time.now}"
Next, we build a hash of HTTP headers, and send the headers by passing the hash into CGI#out. We then generate the output document. Since the end user doesn't usually see the HTTP headers they're served, we'll make them visible by repeating them in the output document (Figure 14-1):
	# Create a hash of HTTP response headers.

	header = { 'status'      => 'OK',

	           'cookie'      => [cookie],

	           'Refresh'     => 2,

	           'Recipe Name' => 'Setting HTTP Response Headers',

	           'server'      => ENV['SERVER_SOFTWARE'] }



	cgi.out(header) do

	  cgi.html('PRETTY' => ' ') do

	    cgi.head { cgi.title { 'Setting HTTP Response Headers' } } +

	    cgi.body do

	      cgi.p('Your headers:') +

	      cgi.pre{ cgi.header(header) } +

	      cgi.pre do

	        "Number of times your browser hit this cgi: #{hits}\n"+

	        "Last connected: #{last}"

	      end

	    end

	 end

	end
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Handling File Uploads via CGI
Inhaltsvorschau
Credit: Mauro Cicio
You want to let a visitor to your web site upload a file to the web server, either for storage or processing.
The CGI class provides a simple interface for accessing data sent through HTTP file upload. You can access an uploaded file through CGI#params as though it were any other CGI form variable.
If the uploaded file size is smaller than 10 kilobytes, its contents are made available as a StringIO object. Otherwise, the file is put into a Tempfile on disk: you can read the file from disk and process it, or move it to a permanent location.
Here's a CGI that accepts file uploads and saves the files to a special directory on disk:
	#!/usr/bin/ruby

	# upload.rb



	# Save uploaded files to this directory

	UPLOAD_DIR = "/usr/local/www/uploads"



	require 'cgi'

	require 'stringio'
The CGI has two main parts: a method that prints a file upload form and a method that processes the results of the form. The method that prints the form is very simple:
	def display_form(cgi)

	 action = env['script_name']

	 return <<EOF

	<form action="#{action}" method="post" enctype="multipart/form-data">

	 File to Upload: <input type="file" name="file_name"><br>

	 Your email address: <input type="text" name="email_address"

	                      value="guest@example.com"><br>

	 <input type="submit" name="Submit" value="Submit Form">

	 </form>

	EOF

	end
The method that processes the form is a little more complex:
	def process_form(cgi)

	  email = cgi.params['email_address'][0] 

fileObj = cgi.params['file_name'][0]



	  str = '<h1>Upload report</h1>' +

	    "<p>Thanks for your upload, #{email.read}</p>"

	  if fileObj

	    path = fileObj.original_filename

	    str += "Original Filename : #{path}" + cgi.br

	    dest = File.join(UPLOAD_DIR, sanitize_filename(path))



	    str += "Destination : #{dest} <br>"

	    File.open(dest.untaint, 'wb') { |f| f << fileObj.read }



	    # Delete the temporary file if one was created

	    local_temp_file = fileObj.local_path()

	    File.unlink(local_temp_file) if local_temp_file

	  end

	  return str

	end
The process_form
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Running Servlets with WEBrick
Inhaltsvorschau
Credit: John-Mason Shackelford
You want to embed a server in your Ruby application. Your project is not a traditional web application, or else it's too small to justify the use of a framework like Rails or Nitro.
Write a custom servlet for WEBrick, a web server implemented in Ruby and included in the standard library.
Configure WEBrick by creating a new HTTPServer instance and mouting servlets. The default FileHandler acts like a "normal" web server: it serves a URL-space corresponding to a directory on disk. It delegates requests for *.cgi files to the CGIHandler, renders *.rhtml files with ERb using the ERBHandler servlet, and serves other files (such as static HTML files) as they are.
This server mounts three servlets on a server running on port 8000 on your local machine. Each servlet serves documents, CGI scripts, and .rhtml templates from a different directory on disk:
	#!/usr/bin/ruby

	# simple_servlet_server.rb

	require 'webrick'

	include WEBrick



	s = HTTPServer.new(:Port => 8000)

	# Add a mime type for *.rhtml files

	HTTPUtils::DefaultMimeTypes.store('rhtml', 'text/html')



	# Required for CGI on Windows; unnecessary on Unix/Linux

	s.config.store( :CGIInterpreter, "#{HTTPServlet::CGIHandler::Ruby}")



	# Mount 

servlets

	s.mount('/',       HTTPServlet::FileHandler, '/var/www/html')

	s.mount('/bruce',  HTTPServlet::FileHandler, '/home/dibbbr/htdoc')

	s.mount('/marty',  HTTPServlet::FileHandler, '/home/wisema/htdoc')



	# Trap signals so as to shutdown cleanly.

	['TERM', 'INT'].each do |signal|

	  trap(signal){ s.shutdown }

	end



	# Start the server and block on input.

	s.start
WEBrick is robust, mature, and easy to extend. Beyond serving static HTML pages, WEBrick supports traditional CGI scripts, ERb-based templating like PHP or JSP, and custom servlet classes. While most of WEBrick's API is oriented toward responding to HTTP requests, you can also use it to implement servers that speak another protocol. (For more on this capability, see the Daytime server example on the WEBrick home page.)
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
A Real-World HTTP Client
Inhaltsvorschau
The first three recipes in this chapter cover different ways of fetching web pages. The techniques they describe work well if you just need to fetch one specific web page, but in the interests of simplicity they omit some details you'll need to consider when writing a web spider, a web browser, or any other serious HTTP client. This recipe creates a library that deals with the details.
Mixed HTTP and HTTPS
Any general client will have to be able to make both HTTP and HTTPS requests. But the simple Net:HTTP methods that work in Recipe 14.1 can't be used to make HTTPS requests. Our library will use use HTTPRequest objects for everything. If the user requests a URL that uses the "https" scheme, we'll flip the request object's use_ssl switch, as seen in Recipe 14.2.
Redirects
Lots of things can go wrong with an HTTP request: the page might have moved, it might require authentication, or it might simply be gone. Most HTTP errors call for higher-level handling or human intervention, but when a page has moved, a smart client can automatically follow it to its new location.
Our library will automatically follow redirects that provide "Location" fields in their responses. It'll prevent infinite redirect loops by refusing to visit a URL it's already visited. It'll prevent infinite redirect chains by limiting the number of redirects. After all the redirects are followed, it'll make the final URI available as a member of the response object.
Proxies
Users use HTTP proxies to make high-latency connections work faster, surf anonymously, and evade censorship. Each individual client program needs to be programmed to use a proxy, and it's an easy feature to overlook if you don't use a proxy yourself. Fortunately, it's easy to support proxies in Ruby: the Proxy class will create a custom Net::HTTP subclass that works through a certain proxy.
This library defines a single new method: Net::HTTP.fetch, an all-singing, all-dancing factory for HTTPRequest objects. It silently handles HTTPS URLs (assuming you have
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Chapter 15: Web Development: Ruby on Rails
Inhaltsvorschau
Ruby on Rails is unquestionably Ruby's killer app. It can take a lot of credit for lifting Ruby from obscurity outside its native Japan. No other programming language can boast a simple web application framework that also has almost all of that language's developer mindshare. This chapter demonstrates the principles underlying basic Rails usage (in recipes like Recipe 15.6), gives Rails implementations of common web application patterns (Recipes 15.4 and 15.8) and shows how to use standard Ruby tools from within Rails (Recipes 15.22 and 15.23).
Despite its quality and popularity, Rails does not bring anything new to web development. Its foundations are in standard programming patterns like ActiveRecord and Model-View-Controller. It reuses many preexisting Ruby libraries (like Rake and ERb). The power of Rails is in combining these standard techniques with a ruthless dedication to automating menial tasks, and to asserting resonable default behaviors.
If Rails has a secret, it's the power of naming conventions. The vast majority of web applications are CRUD applications: create, read, update, and delete information from a database. In these types of applications, Rails shines. You start with a database schema and with almost no code, but Rails ties together many pieces with naming conventions and shortcuts. This lets you put meat on your application very quickly.
Because so many settings and names can be sensibly derived from other pieces of information, Rails has much less "paperwork" than other frameworks. Data that's implicit in the code or the database schema doesn't need to be specified anywhere else. An essential part of this system is the ActiveSupport system for pluralizing nouns (Recipe 15.7).
Where naming conventions can't do the job, Rails uses decorator methods to declare relationships between objects. This happens within the Ruby classes affected by those relationships, not in a bloated XML configuration file. The result is a smaller, simpler to understand, and more flexible application.
As mentioned above, Rails is built on top of common Ruby libraries, and many of them are also covered elsewhere in this book. These libraries include ActiveRecord (much of Chapter 13, but especially Recipe 13.11), ActionMailer (Recipe 14.5), ERb (Recipe 1.3), Rake (Chapter 19), and Test::Unit (Recipe 17.7). Some of these predate Rails, and some were written for Rails but can be used outside of it. The opposite is also true: since a Rails application can be used for many purposes, nearly every recipe in this book is useful within a Rails program.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Writing a Simple Rails Application to Show System Status
Inhaltsvorschau
You would like to get started with Rails by building a very simple application.
This example displays the running processes on a Unix system. If you're developing on Windows, you can substitute some other command (such as the output of a dir) or just have your application print a static message.
First, make sure you have the rails gem installed.
To create a Rails application, run the rails command and pass in the name of your application. Our application will be called "status".
	$ rails status

	      create

	      create app/controllers

	      create app/helpers

	      create app/models

	      create app/views/layouts

	      create config/environments

	…
A Rails application needs at least two parts: a controller and a view. Our controller will get information about the system, and our view will display it.
You can generate a controller and the corresponding view with the generate script. The following invocation defines a controller and view that implement a single action called index. This will be the main (and only) screen of our application.
	$ cd status

	$ ./script/generate controller status index

	      exists app/controllers/

	      exists app/helpers/

	      create app/views/status

	      exists test/functional/

	      create app/controllers/status_controller.rb

	      create test/functional/status_controller_test.rb

	      create app/helpers/status_helper.rb

	      create app/views/status/index.rhtml
The generated controller is in the Ruby source file app/controllers/status_controller.rb. That file defines a class StatusController that implements the index action as an empty method called index. Fill out the index method so that it exposes the objects you want to use in the view:
	class StatusController < ApplicationController

	  def index

	    # This variable won't be accessible to the view, since it is local

	    # to this method

	    time = Time.now

	

	    # These variables will be accessible in the view, since they are

	    # instance variables of the StatusController.

	    @time = time

	    @ps = 'ps aux'

	  end

	end
The generated view is in
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Passing Data from the Controller to the View
Inhaltsvorschau
You want to pass data between a controller and its views.
The view is an ERB template that is interpreted within the context of its controller object. A view cannot call any of the controller's methods, but it can access the controller's instance variables. To pass data to the view, set an instance variable of the controller.
Here's a NovelController class, to be put into app/ controllers/novel_controller.rb. You can generate stubs for it by running script/generate controller novel index.
	class NovelController < ApplicationController

	  def index

	    @title = 'Shattered View: A Novel on 

Rails'

	    one_plus_one = 1 + 1

	    increment_counter one_plus_one

	  end



	  def helper_method

	    @help_message = "I see you've come to me for help."

	  end



	  private



	  def increment_counter(by)

	    @counter ||= 0

	    @counter += by

	  end

	end
Since this is the Novel controller and the index action, the corresponding view is in app/views/novel/index.rhtml.
	<h1><%= @title %></h1>

	

	<p>I looked up, but saw only the number <%= @counter %>.</p>

	

	<p>"What are you doing here?" I asked sharply. "Was it <%=

	@counter.succ %> who sent you?"</p>
The view is interpreted after NovelController#index is run. Here's what the view can and can't access:
  • It can access the instance variables @title and @counter, because they've been defined on the NovelController object by the time NovelController#index finishes running.
  • It can call instance methods of the instance variables @title and @counter.
  • It cannot access the instance variable @help_message, because that variable is defined by the method helper_method, which never gets called.
  • It cannot access the variable one_plus_one, because that's not an instance variable: it's local to the index method.
  • Even though it runs in the context of NovelController, it cannot call any method of NovelController—neither helper_method nor set_another_variable. Nor can it call index again.
The action method of a controller is responsible for creating and storing (in instance variables) all the objects the view will need to do its job. These variables might be as simple as strings, or they might be complex helper classes. Either way, most of your application's logic should be in the controller. It's okay to do things in the view like iterate over data structures, but most of the work should happen in the controller or in one of the objects it exposes through an instance variable.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Creating a Layout for Your Header and Footer
Inhaltsvorschau
You want to create a header and footer for every page on your web application. Certain pages should have special headers and footers, and you may want to dynamically determine which header and footer to use for a given request.
Many web applications let you define header and footer files, and automatically include those files at the top and bottom of every page. Rails inverts this pattern. A single file called contains both the header and footer, and the contents of each particular page are inserted into this file.
To apply a layout to every page in your web application, create a file called app/views/layouts/application.rhtml. It should look something like this:
	<html>

	  <head>

	    <title>My Website</title>

	 </head>

	  <body>

	    <%= @content_for_layout %>

	  </body>

	</html>
The key piece of information in any layout file is the directive <%= content_for_layout %>. This is replaced by the content of each individual page.
You can make customized layouts for each controller independently by creating files in the app/views/layouts folder. For example, app/views/layouts/status.rhtml is the layout for the status controller, StatusController. The layout file for PriceController would be price.rhtml.
Customized layouts override the site-wide layout; they don't add to it.
Just like your main view templates, your layout templates have access to all the instance variables set by the action. Anything you can do in a view, you can do in a layout template. This means you can do things like set the page title dynamically in the action, and then use it in the layout:
	class StatusController < ActionController:Base

	  def index

	    @title = "System Status"

	  end

	end
Now the application.rhtml file can access @title like this:
	<html>

	  <head>

	     <title>My Website - <%= @title %></title>

	  </head>

	  <body>

	     <%= @content_for_ 

layout %>

	  </body>

	</html>
application.rhtml doesn't just happen to be the default layout template for a Rails application's controllers. It happens this way because every controller inherits from ApplicationController. By default, a layout's name is derived from the name of the controller's class. So
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Redirecting to a Different Location
Inhaltsvorschau
You want to redirect your user to another of your application's actions, or to an external URL.
The class ActionController::Base (superclass of ApplicationController) defines a method called redirect_to, which performs an HTTP redirect. To redirect to another site, you can pass it a URL as a string. To redirect to a different action in your application, pass it a hash that specifies the controller, action, and ID.
Here's a BureaucracyController that shuffles incoming requests to and fro between various actions, finally sending the client to an external site:
	class BureaucracyController < ApplicationController

	  def index

	    redirect_to :controller => 'bureaucracy', :action => 'reservation_window'

	  end



	  def reservation_window

	    redirect_to :action => 'claim_your_form', :id => 123

	  end



	  def claim_your_form

	    redirect_to :action => 'fill_out_your_form', :id => params[:id]

	  end



	  def fill_out_your_form

	    redirect_to :action => 'form_processing'

	  end



	  def form_processing

	    redirect_to "http://www.dmv.org/"

	  end

	end
If you run the Rails server and hit http://localhost:3000/bureaucracy/ in your browser, you'll end up at http://www.dmv.org/. The Rails server log will show the chain of HTTP requests you made to get there:
	"GET /bureaucracy HTTP/1.1" 302

	"GET /bureaucracy/reservation_window HTTP/1.1" 302

	"GET /bureaucracy/claim_your_form/123 HTTP/1.1" 302

	"GET /bureaucracy/fill_out_your_form/123 HTTP/1.1" 302

	"GET /bureaucracy/form_processing HTTP/1.1" 302
You don't need to create view templates for all of these actions, because the body of an HTTP redirect isn't displayed by the web browser.
The redirect_to method uses smart defaults. If you give it a hash that doesn't specify a controller, it assumes you want to move to another action in the same controller. If you leave out the action, it assumes you are talking about the index action.
From the simple redirects given in the Solution, you might think that calling redirect_to actually stops the action method in place and does an immediate HTTP redirect. This is not true. The action method continues to run until it ends or you call return. The
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Displaying Templates with Render
Inhaltsvorschau
Rails's default mapping of one action method to one view template is not flexible enough for you. You want to customize the template that gets rendered for a particular action by calling Rails's rendering code directly.
Rendering happens in the ActionController::Base#render method. Rails's default behavior is to call render after the action method runs, mapping the action to a corresponding view template. The foo action gets mapped to the foo.rhtml template.
You can call render from within an action method to make Rails render a different template. This controller defines two actions, both of which are rendered using the shopping_list.rhtml template:
	class ListController < ApplicationController

	  def index

	    @list = ['papaya', 'polio vaccine']

	    render :action => 'shopping_list'

	  end



	  def shopping_list

	    @list = ['cotton balls', 'amino acids', 'pie']

	  end

	end
By default, render assumes that you are talking about the controller and action that are running when render is called. If you call render with no arguments, Rails will work the same way it usually does. But specifying 'shopping_list' as the view overrides this default, and makes the index action use the shopping_list.rhtml template, just like the shopping_list action does.
Although they use the same template, visiting the index action is not the same as visiting the shopping_list action. They display different lists, because index defines a different list from shopping_list.
Recall from Recipe 15.4 that the redirect method doesn't perform an immediate HTTP redirect. It tells Rails to do a redirect once the current action method finishes running. Similarly, the render method doesn't do the rendering immediately. It only tells Rails which template to render when the action is complete.
Consider this example:
	class ListController < ApplicationController

	  def index

	    render :action => 'shopping_list'

	    @budget = 87.50

	  end



	  def shopping_list

	    @list = ['lizard food', 'baking soda']

	  end

	end
You might think that calling index sets @list but not @budget. Actually, the reverse is true. Calling
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Integrating a Database with Your Rails Application
Inhaltsvorschau
You want your web application to store persistent data in a relational database.
The hardest part is setting things up: creating your database and hooking Rails up to it. Once that's done, database access is as simple as writing Ruby code.
To tell Rails how to access your database, open your application's config/database.yml file. Assuming your Rails application is called mywebapp, it should look something like this:
	development:

	adapter: mysql

	database: mywebapp_development

	host: localhost

	username: root

	password:



	test:

	adapter: mysql

	database: mywebapp_test

	host: localhost

	username: root

	password:



	production:

	adapter: mysql

	database: mywebapp

	host: localhost

	username: root

	password:
For now, just make sure the development section contains a valid username and password, and that it mentions the correct adapter name for your type of database (see Chapter 13 for the list).
Now create a database table. As with so much else, Rails does a lot of the database work automatically if you follow its conventions. You can override the conventions if necessary, but for now it's easiest to go along with them.
The name of the table must be a pluralized noun: for instance, "people", "tasks", "items".
The table must contain an auto-incrementing primary key field called id.
For this example, use a database tool or a CREATE DATABASE SQL command to create a mywebapp_development database (see the chapter introduction for Chapter 13 if you need help doing this). Then create a table in that database called people. Here's the SQL to create a people table in MySQL; you can adapt it for your database.
	use mywebapp_development;



	DROP TABLE IF EXISTS 'people';

	CREATE TABLE 'people' (

	'id' INT(11) NOT NULL AUTO_INCREMENT,

	'name' VARCHAR(255),

	'email' VARCHAR(255),

	PRIMARY KEY (id)

	) ENGINE=InnoDB;
Now go to the command line, change into the web application's root directory, and type ./script/generate model Person. This generates a Ruby class that knows how to manipulate the people table.
	$ ./script/generate model Person

	exists app/models/

	exists test/unit/

	exists test/fixtures/

	create app/models/person.rb

	create test/unit/person_test.rb

	create test/fixtures/people.yml
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Understanding Pluralization Rules
Inhaltsvorschau
You want to understand and customize Rails's rules for automatically pluralizing nouns.
You can use Rails' pluralization functionality in any part of your application, but ActiveRecord is the only major part of Rails that does pluralization automatically. ActiveRecord generally expects table names to be pluralized noun phrases and the corresponding model classes to be singular versions of the same noun phrases.
So when you create a model class, you should always use a singular name. Rails automatically pluralizes:
  • The corresponding table name for the model
  • has_many relations
  • has_and_belongs_to_many relations
For example, if you create a LineItem model, the table name automatically becomes line_items. Note also that the table name has been lowercased, and the word break indicated by the original camelcase is now conveyed with an underscore.
If you then create an Order model, the corresponding table needs to be called orders. If you want to describe an order that has many line items, the code would look like this:
	class Order < ActiveRecord::Base

	  has_many :line_items

	end
Like the name of the table it references, the symbol used in the has_many relation is pluralized and underscored. The same goes for the other relationships between tables, like has_and_belongs_to_many.
ActiveRecord pluralizes these names to make your code read more like an English sentence: has_many :line_items can be read "has many line items". If pluralization confuses you, you can disable it by setting ActiveRecord::Base.pluralize_table_names to false. In Rails, the simplest way to do this is to put the following code in config/environment.rb:
	Rails::Initializer.run do |config|

	  config.active_record.pluralize_table_names = false

	end
If your application knows specific words that ActiveRecord does not know how to pluralize, you can define your own pluralization rules by manipulating the Inflector class. Let's say that the plural of "foo" is "fooze", and you've build an application to manage fooze. In Rails, you can specify this transformation by putting the following code in
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Creating a Login System
Inhaltsvorschau
You want your application to support a login system based on user accounts. Users will log in with a unique username and password, as in most commercial and community web sites.
Create a users table that contains nonnull username and password fields. The SQL to create this table should look something like this MySQL example:
	use mywebapp_development;

	DROP TABLE IF EXISTS 'users';

	CREATE TABLE 'users' (

	  'id' INT(11) NOT NULL AUTO_INCREMENT,

	  'username' VARCHAR(255) NOT NULL,

	  'password' VARCHAR(40) NOT NULL,

	  PRIMARY KEY ('id')

	);
Enter the main directory of the application and generate a User model corresponding to this table:
	$ ./script/generate model User

	      exists app/models/

	      exists test/unit/

	      exists test/fixtures/

          create app/models/user.rb

	      create test/unit/user_test.rb

	      create test/fixtures/users.yml
Open the generated file app/models/user.rb and edit it to look like this:
	class User < ActiveRecord::Base

	  validates_uniqueness_of :username

	  validates_confirmation_of :password, :on => :create

	  validates_length_of :password, :within => 5..40



	  # If a user matching the credentials is found, returns the User object.

	  # If no matching user is found, returns nil.

	  def self.authenticate(user_info)

	    find_by_username_and_password(user_info[:username],

	                                  user_info[:password])

	  end

	end
Now you've got a User class that represents a user account, and a way of validating a username and password against the one stored in the database.
The simple User model given in the Solution defines a method for doing username/password validation, and some validation rules that impose limitations on the data to be stored in the users table. These validation rules tell User to:
  • Ensure that each username is unique. No two users can have the same username.
  • Ensure that, whenever the password attribute is being set, the password_confirmation attribute has the same value.
  • Ensure that the value of the password attribute is between 5 and 40 characters long.
Now let's create a controller for this model. It'll have a
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Storing Hashed User Passwords in the Database
Inhaltsvorschau
The database table defined in Recipe 15.8 stores users' passwords as plain text. This is a bad idea: if someone compromises the database, she will have all of your users' passwords. It's best to store a secure hash of the password instead. That way, you don't have the password (so no one can steal it), but you can verify that a user knows his password.
Recreate the users table from Recipe 15.8 so that instead of a password field, it has a hashed_password field. Here's some MySQL code to do that:
	use mywebapp_development;

	DROP TABLE IF EXISTS 'users';

	CREATE TABLE 'users' (

	  'id' INT(11) NOT NULL AUTO_INCREMENT,

	  'username' VARCHAR(255) NOT NULL,

	  'hashed_password' VARCHAR(40) NOT NULL,

	  PRIMARY KEY (id)

	);
Open the file app/models/user.rb created in Recipe 15.8, and edit it to look like this:
	require 'sha1'

	

	class User < ActiveRecord::Base

	  attr_accessor :password

	  attr_protected :hashed_password

	  validates_uniqueness_of :username

	  validates_confirmation_of : 

password,

	    :if => lambda { |user| user.new_record? or not user.password.blank? }

	  validates_length_of :password, :within => 5..40,

	    :if => lambda { |user| user.new_record? or not user.password.blank? }



	  def self.hashed(str)

	    SHA1.new(str).to_s

	  end



	  # If a user matching the credentials is found, returns the User object.

	  # If no matching user is found, returns nil.

	  def self.authenticate(user_info)

	    user = find_by_username(user_info[:username])

	    if user && user.hashed_password == hashed(user_info[:password])

	      return user

	    end

	  end



	  private

	  before_save :update_password



	  # Updates the hashed_password if a plain password was provided.

	  def update_password

	    if not password.blank?

	      self.hashed_password = self.class.hashed(password)

	    end

	  end

	end
Once you do this, your application will work as before (though you'll have to convert any preexisting user accounts to the new password format). You don't need to modify any of the controller or view code, because the User.authenticate method works the same way it did before. This is one of the benefits of separating business logic from presentation logic.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Escaping HTML and JavaScript for Display
Inhaltsvorschau
You want to display data that might contain HTML or JavaScript without making browsers render it as HTML or interpret the JavaScript. This is especially important when displaying data entered by users.
Pass a string of data into the h() helper function to escape its HTML entities. That is, instead of this:
	<%= @data %>
Write this:
	<%=h @data %>
The h() helper function converts the following characters into their HTML entity equivalents: ampersand (&), double quote ("), left angle bracket (<), and right angle bracket (>).
You won't find the definition for the h() helper function anywhere in the Rails source code, because it's a shortcut for ERb's built-in helper function html_escape().
JavaScript is deployed within HTML tags like <SCRIPT>, so escaping an HTML string will neutralize any JavaScript in the HTML. However, sometimes you need to escape just the JavaScript in a string. Rails adds a helper function called escape_javascript() that you can use. This function doesn't do much: it just turns line breaks into the string "\n", and adds backslashes before single and double quotes. This is handy when you want to use arbitrary data in your own JavaScript code:
	<!-- index.rhtml -->

	<script lang="javascript">

	var text = "<%= escape_javascript @javascript_alert_text %>";

	alert(text);

	</script>
  • Chapter 11
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Setting and Retrieving Session Information
Inhaltsvorschau
You want to associate some data with each distinct web client that's using your application. The data needs to persist across HTTP requests.
You can use cookies (see Recipe 15.12) but it's usually simpler to put the data in a user's session. Every visitor to your Rails site is automatically given a session cookie. Rails keys the value of the cookie to a hash of arbitrary data on the server.
Throughout your entire Rails application, in controllers, views, helpers, and mailers, you can access this hash by calling a method called session. The objects stored in this hash are persisted across requests by the same web browser.
This code in a controller tracks the time of a client's first visit to your web site:
	class IndexController < ApplicationController

	  def index

	    session[:first_time] ||= Time.now

	  end

	end
Within your view, you can write the following code to display the time:
	<!-- index.rhtml -->

	You first visited this site on <%= session[:first_time] %>.



	That was <%= time_ago_in_words session[:first_time] %> ago.
Cookies and sessions are very similar. They both store persistent data about a visitor to your site. They both let you implement stateful operations on top of HTTP, which has no state of its own. The main difference between cookies and sessions is that with cookies, all the data is stored on your visitors' computers in little cookie files. With sessions, all the data is stored on the web server. The client only keeps a small session cookie, which contains a unique ID that's tied to the data on the server. No personal data is ever stored on the visitor's computer.
There are a number of reasons why you might want to use sessions instead of cookies:
  • A cookie can only store four kilobytes of data.
  • A cookie can only store a string value.
  • If you store personal information in a cookie, it can be intercepted unless all of a client's requests are encrypted with SSL. Even then, cross-site scripting attacks may be able to read the client cookie and retrieve the sensitive information.
On the other hand, cookies are useful when:
  • The information is not sensitive and not very large.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Setting and Retrieving Cookies
Inhaltsvorschau
You want to set a cookie from within Rails.
Recall from Recipe 15.11 that all Rails controllers, views, helpers, and mailers have access to a method called sessions that returns a hash of the current client's session information. Your controllers, helpers, and mailers (but not your views) also have access to a method called cookies, which returns a hash of the current client's HTTP cookies.
To set a cookie for a user, simply set a key/value pair in that hash. For example, to keep track of how many pages a visitor has looked at, you might set a "visits" cookie:
	class ApplicationController < ActionController::Base

	  before_filter :count_visits



	  private



	  def count_visits

	    value = (cookies[:visits] || '0').to_i

	    cookies[:visits] = (value + 1).to_s

	    @visits = cookies[:visits]

	  end

	end
The call to before_filter tells Rails to run this method before calling any action method. The private declaration makes sure that Rails doesn't think the count_visits method is itself an action method that the public can view.
Since cookies are not directly available to views, count_visits makes the value of the :visits cookie available as the instance variable @visits. This variable can be accessed from a view:
	<!-- index.rhtml -->

	You've visited this website's pages <%= @visits %> time(s).
HTTP cookie values can only be strings. Rails can automatically convert some values to strings, but it's safest to store only string values in cookies. If you need to store objects that can't easily be converted to and from strings, you should probably store them in the session hash instead.
There may be times when you want more control over your cookies. For instance, Rails cookies expire by default when the user closes their browser session. If you want to change the browser expiration time, you can give cookies a hash that contains an :expires key and a time to expire the cookie. The following cookie will expire after one hour:
	cookies[:user_id] = { :value => '123', :expires => Time.now + 1.hour}
Here are some other options for a cookie hash passed into
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Extracting Code into Helper Functions
Inhaltsvorschau
Your views are getting cluttered with Ruby code.
Let's create a controller with a fairly complex view to see how this can happen:
	$ ./scripts/generate controller list index

	      exists app/controllers/

	      exists app/helpers/

	      create app/views/list

	      exists test/functional/

	      create app/controllers/list_controller.rb

	      create test/functional/list_controller_test.rb

	      create app/helpers/list_helper.rb

	      create app/views/list/index.rhtml
Edit app/controllers/list_controller.rb to look like this:
	class ListController < ApplicationController

	  def index

	    @list = [1, "string", :symbol, ['list']]

	  end

	end
Edit app/views/list/index.rhtml to contain the following code. It iterates over each element in @list, and prints out its index and the SHA1 hash of its object ID:
	<!-- app/views/list/index.rhtml -->

	<ul>

	<% @list.each_with_index do |item, i| %>

	  <li class="<%= i%2==0 ? 'even' : 'odd' %>"><%= i %>:

	    <%= SHA1.new(item.id.to_s) %></li>

	<% end %>

	</ul>
This is pretty messy, but if you've done much web programming it should also look sadly familiar.
To clean up this code, we're going to move some of it into the helper for the controller. In this case, the controller is called list, so its helper lives in app/helpers/list_helper.rb.
Let's create a helper function called create_li. Given an object and its position in the list, this function creates an <LI> tag suitable for use in the index view:
	module ListHelper

	  def create_li(item, i)

	    %{<li class="#{ i%2==0 ? 'even' : 'odd' }">#{i}:

	      #{SHA1.new(item.id.to_s)}</li>}

	  end

	end
The list controller's views have access to all the functions defined in ListHelper. We can clean up the index view like so:
	<!-- app/ 

views/list/index.rhtml -->

	<ul>

	<% @list.each_with_index do |item, i| %>

	  <%= create_li(item, i) %>

	<% end %>

	</ul>
Your helper functions can do anything you can normally do from within a view, so they are a great way to abstract out the heavy lifting.
The purpose of helper functions is to create more maintainable code, and to enforce a good division of labor between the programmers and the UI designers. Maintainable code is easier for the programmers to work on, and when it's in helper functions it's out of the way of the designers, who can tweak the HTML here and there without having to sifting through code.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Refactoring the View into Partial Snippets of Views
Inhaltsvorschau
Your view doesn't contain a lot of Ruby code, but it's still becoming more complicated than you'd like. You'd like to refactor the view logic into separate, reusable templates.
You can refactor a view template into multiple templates called partials. One template can include another by calling the render method, first seen in Recipe 15.5.
Let's start with a more complex version of the view shown in Recipe 15.5:
	<!-- app/ 

views/list/shopping_list.rhtml -->

	<h2>My shopping list</h2>



	<ul>

	 <% @list.each do |item| %>

	  <li><%= item.name %>

	   <%= link_to 'Delete', {:action => 'delete', :id => item.id},

	                  :post => true %>



	  </li>

	<% end %>

	</ul>



	<h2>Add a new item</h2>



	<%= form_tag :action => 'new' %>

	 Item: <%= text_field "product", "name" %>&#x00A;

	 <%= submit_tag "Add new item" %>

	<%= end_form_tag %>
Here's the corresponding controller class, and a dummy ListItem class to serve as the model:
	# app/controllers/list_controller.rb

	class ListController < ActionController::Base

	  def shopping_list

	    @list = [ListItem.new(4, 'aspirin'), ListItem.new(199, 'succotash')]

	  end



	  # Other actions go here: add, delete, etc.

	  # …

	end

	

	class ListItem

	  def initialize(id, name)

	    @id, @name = id, name

	  end

	end
The view has two parts: the first part lists all the items, and the second part prints a form to add a new item. An obvious first step is to split out the new item form.
We can do this by creating a partial view to print the new item form. To do this, create a new file within app/ views/list/ called _new_item_form.rhtml. The underscore in front of the filename indicates that it is a partial view, not a full-fledged view for an action called new_item_form. Here's the partial file.
	<!-- app/ 

views/list/_new_item_form.rhtml -->



	<%= form_tag :action => 'new' %>

	Item: <%= text_field "item", "value" %>&#x00A;

	<%= submit_tag "Add new item" %>

	<%= end_form_tag %>
To include a partial, call the render method from within a template. Here is the _new_item_form partial integrated into the main view. The view looks exactly the same, but the code is better organized.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Adding DHTML Effects with script.aculo.us
Inhaltsvorschau
You want to add fancy effects such as fades to your application, without writing any JavaScript.
Every Rails application comes bundled with some JavaScript libraries that allow you to create Ajax and DHTML effects. You don't even have to write JavaScript to enable DHTML in your Rails web site.
First edit your main layout template (see Recipe 15.3) to call javascript_include_tag within your <HEAD> tag:
	<!-- app/views/layouts/application.rhtml -->



	<html>

	  <head>

	    <title>My Web App</title><%= javascript_include_tag "prototype", "effects" %>

	  </head>

	  <body>

	    <%= @content_for_layout %>

	  </body>

	</html>
Now within your views you can call the visual_effect method to accomplish the DHTML tricks found in the script.aculo.us library.
Here's an example of the "highlight" effect:
	<p id="important">Here is some important text, it will be highlighted

	when the page loads.</p>



	<script type="text/javascript">

	<%= visual_effect(:highlight, "important", :duration => 1.5) %>

	</script>
Here's an example of the "fade" effect:
	<p id="deleted">Here is some old text, it will fade away when the page

	loads.</p>

	<script type="text/javascript">

	<%= visual_effect(:fade, "deleted", :duration => 1.0) %>

	</script>
The sample code snippets above are triggered when the page loads, because they're enclosed in <SCRIPT> tags. In a real application, you'll probably display text effects in response to user actions: deleted items might fade away, or the selection of one item might highlight related items. Here's an image that gets squished when you click the link below it:
	<img id="to-squish" src="bug.jpg">

	<%=link_to_function("Squish the bug!", visual_effect(:squish, "to-squish"))%>
The JavaScript code generated by the visual_effect method looks a lot like the arguments you passed into the method. For instance, this piece of a Rails view:
	<script type="text/javascript">

	<%= visual_effect(:fade, 'deleted-text', :duration => 1.0) %>

	</script>
Generates this JavaScript:
	<script type="text/javascript">

	new Effect.Fade("deleted-text", {duration:1.0});

	</script>
This similarity means that documentation for the
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Generating Forms for Manipulating Model Objects
Inhaltsvorschau
You want to define actions that let a user create or edit objects stored in the database.
Let's create a simple model, and then build forms for it. Here's some MySQL code to create a table of key-value pairs:
	use mywebapp_development;

	DROP TABLE IF EXISTS items;

	CREATE TABLE `items` (

	  'id' int(11) NOT NULL auto_increment,

	  'name' varchar(255) NOT NULL default '',

	  'value' varchar(40) NOT NULL default '[empty]',

	  PRIMARY KEY ('id')

	);
Now, from the command line, create the model class, along with a controller and views:
	$ ./script/generate model Item

	      exists app/models/

	      exists test/unit/

	      exists test/fixtures/

	      create app/models/item.rb

	      create test/unit/item_test.rb

	      create test/fixtures/items.yml

 	      create db/migrate

	      create db/migrate/001_create_items.rb

	$ ./script/generate controller items new create edit

	      exists app/controllers/

	      exists app/helpers/

	      create app/views/items

	      exists test/functional/

	      create app/controllers/items_controller.rb

	      create test/functional/items_controller_test.rb

	      create app/helpers/items_helper.rb

	      create app/views/items/new.rhtml

	      create app/views/items/edit.rhtml
The first step is to customize a view. Let's start with app/views/items/new.rhtml. Edit it to look like this:
	<!-- app/views/items/new.rhtml -->

	 

	<%= form_tag :action => "create" %>

	 Name: <%= text_field "item", "name" %><br />

	 Value: <%= text_field "item", "value" %><br />

	 <%= submit_tag %>

	<%= end_form_tag %>
All these method calls generate HTML: form_tag opens a <FORM> tag, submit_tag generates a submit button, and so on. You can type out the same HTML by hand and Rails won't care, but it's easier to make method calls, and it makes your templates neater.
The text_field call is a little more involved. It creates an <INPUT> tag that shows up in the HTML form as a text entry field. But it also binds the value of that field to one of the members of the @item instance variable. This code creates a text entry field that's bound to the name member of @item
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Creating an Ajax Form
Inhaltsvorschau
You want to build a web application that's responsive and easy to use. You don't want your users to spend lots of time waiting around for the browser to redraw the screen.
You can use JavaScript to make the browser's XMLHTTPRequest object send data to the server, without dragging the user through the familiar (but slow) page refresh. This technique is called Ajax, and Rails makes it easy to use Ajax without writing or knowing any JavaScript.
Before you can do Ajax in your web application, you must edit your application's main layout template so that it calls the javascript_include_tag method within its <HEAD> tag. This is the same change made in Recipe 15.15:
	<!-- app/views/layouts/application.rhtml -->



	<html>

	  <head>

	    <title>My Web App</title><%= javascript_include_tag "prototype", "effects" %>

	  </head>

	  <body>

	    <%= @content_for_layout %>

	  </body>

	</html>
Let's change the application from Recipe 15.16 so that the new action is AJAXenabled (if you followed that recipe all the way through, and made the edit action use new.rhtml instead of edit.rhtml, you'll need to undo that change and make edit use its own view template).
We'll start with the view template. Edit app/views/items/new.rhtml to look like this:
	<!-- app/views/items/new.rhtml --><div id="show_item"></div>

	

	         <%= form_remote_tag :url => { :action => :create },

	         :update => "show_item",

	         :complete => visual_effect(:highlight, "show_item") %>



	 Name: <%= text_field "item", "name" %><br />

	 Value: <%= text_field "item", "value" %><br />

	 <%= submit_tag %>

	<%= end_form_tag %>
Those small changes make a standard HTML form into an Ajax form. The main difference is that we call form_remote_tag instead of form_tag. The other differences are the arguments we pass into that method.
The first change is that we put the :action parameter inside a hash passed into the :url option. Ajax forms have more options associated with them than a normal form, so you can't describe its form action as simply as you can with form_tag.
When the user clicks the submit button, the form values are serialized and sent to the destination action (in this case,
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Exposing Web Services on Your Web Site
Inhaltsvorschau
You want to offer SOAP and XML-RPC web services from your web application.
Rails comes with a built-in web service generator that makes it easy to expose a controller's actions as web services. You don't have to spend time writing WSDL files or even really know how SOAP and XML-RPC work.
Here's a simple example. First, follow the directions in Recipe 15.16 to create a database table named items, and to generate a model for that table. Don't generate a controller.
Now, run this from the command line:
	./script/generate web_service Item add edit fetch

	      create app/apis/

	      exists app/controllers/

	      exists test/functional/

	      create app/apis/item_api.rb

	      create app/controllers/item_controller.rb

	      create test/functional/item_api_test.rb
This creates an item controller that supports three actions: add, edit, and fetch. But instead of web application actions with .rhtml views, these are web service actions that you access with SOAP or XML-RPC.
A Ruby method doesn't care about the data types of the objects it accepts as arguments, or the data type of its return value. But a SOAP or XML-RPC web service method does care. To expose a Ruby method through a SOAP or XML-RPC interface, we need to define type information for its signature. Open up the file app/apis/item_api.rb and edit it to look like this:
	class ItemApi < ActionWebService::API::Base

	  api_method :add, :expects => [:string, :string], :returns => [:int]

	  api_method :edit, :expects => [:int, :string, :string], :returns => [:bool]

	  api_method :fetch, :expects => [:int], :returns => [Item]

	end
Now we need to implement the actual web service interface. Open app/controllers/item_controller.rb and edit it to look like this:
	class ItemController < ApplicationController

	  wsdl_service_name 'Item'



	  def add(name, value)

	    Item.create(:name => name, :value => value).id

	  end



	  def edit(id, name, value)

	    Item.find(id).update_attributes(:name => name, :value => value)

	  end



	  def fetch(id)

	    Item.find(id)

	  end

	end
The item controller now implements SOAP and XML-RPC web services for the
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Sending Mail with Rails
Inhaltsvorschau
You want to send an email from within your Rails application: perhaps a confirmation of an order, or notification that some action has been taken on a user's behalf.
The first is to generate some mailer infrastructure. Go to the application's base directory and type this command:
	./script/generate mailer Notification welcome

	      exists app/models/

	      create app/views/notification

	      exists test/unit/

	      create test/fixtures/notification

	      create app/models/notification.rb

	      create test/unit/notification_test.rb

	      create app/views/notification/welcome.rhtml

	      create test/fixtures/notification/welcome
We're giving the name "Notification" to the mailing center of the application; it's somewhat analogous to a controller in the web interface. The mailer is set up to generate a single email, called "welcome": this is analagous to an action with a view template.
Now open app/models/notification.rb and edit it to look like this:
	class Notification < ActionMailer::Base

	  def welcome(user, sent_at=Time.now)

	    @subject = 'A Friendly Welcome'

	    @recipients = user.email

	    @from = 'admin@mysite.com'

	    @sent_on = sent_at

	    @body = {

	      :user => user,

	      :sent_on => sent_at

	    }

	    attachment 'text/plain' do |a|

	      a.body = File.read('rules.txt')

	    end

	  end

	end
The subject of the email is "A Friendly Welcome", and it's sent to the user's email address from the address "admin@mysite.com". It's got an attachment taken from the disk file rules.txt (relative to the root directory of your Rails application).
Although the file notification.rb is within the models/ directory, it acts like a controller in that each of its email messages has an associated view template. The view for the welcome email is in app/views/notification/welcome.rhtml, and it acts almost the same as the view of a normal controller.
The most important difference is that mailer views do not have access to the instance variables of the mailer. To set instance variables for mailers, you pass a hash of those variables to the body method. The keys become instance variable names and the values become their values. In
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Automatically Sending Error Messages to Your Email
Inhaltsvorschau
You want to receive a descriptive email message every time one of your users encounters an application error.
Any errors that occur while running your application are sent to the ActionController::Base#log_error method. If you've set up a mailer (as shown in Recipe 15.19) you can override this method and have it send mail to you. Your code should look something like this:
	class ApplicationController < ActionController::Base



	private

	   def log_error(exception)

	      super

	      Notification.deliver_error_message(exception,

	        clean_backtrace(exception),

	        session.instance_variable_get("@data"),

	        params,

	        request.env

	      )

	   end

	end
That code rounds up a wide variety of information about the state of the Rails request at the time of the failure. It captures the exception object, the corresponding backtrace, the session data, the CGI request parameters, and the values of all environment variables.
The overridden log_error calls Notification.deliver_error_messsage, which assumes you've created a mailer called "Notification", and defined the method Notification.error_message. Here's the implementation:
	class Notification < ActionMailer::Base

	  def error_message(exception, trace, session, params, env, sent_on = Time.now)

	    @recipients = 'me@mydomain.com'

	    @from = 'error@mydomain.com'

	    @subject = "Error message: #{env['REQUEST_URI']}"

	    @sent_on = sent_on

	    @body = {

	      :exception => exception,

	      :trace => trace,

	      :session => session,

	      :params => params,

	      :env => env

	    }

	  end

	end
The template for this email looks like this:
	<!-- app/views/notification/error_message.rhtml -->



	Time: <%= Time.now %>

	Message: <%= @exception.message %>

	Location: <%= @env['REQUEST_URI'] %>

	Action: <%= @params.delete('action') %></td></tr>

	Controller: <%= @params.delete('controller') %></td></tr>

	Query: <%= @env['QUERY_STRING'] %></td></tr>

	Method: <%= @env['REQUEST_METHOD'] %></td></tr>

	SSL: <%= @env['SERVER_PORT'].to_i == 443 ? "true" : "false" %>

	Agent: <%= @env['HTTP_ 

USER_AGENT'] %>



	Backtrace

	<%= @trace.to_a.join("</p>\n<p>") %>



	Params

	<% @params.each do |key, val| -%>

	* <%= key %>: <%= val.to_yaml %>

	<% end -%>

	Session

	<% @session.each do |key, val| -%>

	* <%= key %>: <%= val.to_yaml %>

	<% end -%>

	

	Environment

	<% @env.each do |key, val| -%>

	* <%= key %>: <%= val %>

	<% end -%>
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Documenting Your Web Site
Inhaltsvorschau
You want to document the controllers, models, and helpers of your web application so that the developers responsible for maintaining the application can understand how it works.
As with any other Ruby program, you document a Rails application by adding specially-formatted commands to your code. Here's how to add documentation to the FooController class and one of its methods:
	# The FooController controller contains miscellaneous functionality

	# rejected from other controllers.

	class FooController < ApplicationController

	  # The set_random action sets the @random_number instance variable

	  # to a random number.

	  def set_random

	    @random_number = rand*rand

	  end

	end
The documentation for classes and methods goes before their declaration, not after.
When you've finished adding documentation comments to your application, go to your Rails application's root directory and issue the rake appdoc command:
	$ rake appdoc
This Rake task runs RDoc for your Rails application and generates a directory called doc/app. This directory contains a web site with the aggregate of all your documentation comments, cross-referenced against the source code. Open the doc/app/index.rhtml file in any web browser, and you can browse the generated documentation.
Your RDoc comments can contain markup and special directives: you can describe your arguments in definition lists, and hide a class or method from documentation with the :nodoc: directive. This is covered in Recipe 17.11.
The only difference between Rails applications and other Ruby programs is that Rails comes with a Rakefile that defines an appdoc task. You don't have to find or write one yourself.
You probably already put inline comments inside your methods, describing the action as it happens. Since the RDoc documentation contains a formatted version of the original source code, these comments will be visible to people going through the RDoc. These comments are formatted as Ruby source code, though, not as RDoc markup.
  • Recipe 17.11, "Documenting Your Application"
  • Chapter 19, especially Recipe 19.2, "Automatically Generating Documentation"
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Unit Testing Your Web Site
Inhaltsvorschau
You want to create a suite of automated tests that test the functionality of your Rails application.
Rails can't write your test code any more than it can write your views and controllers for you, but it does make it easy to organize and run your automated tests.
When you use the ./script/generate command to create controllers and models, not only do you save time, but you also get a generated framework for unit and functional tests. You can get pretty good test coverage by filling in the framework with tests for the functionality you write.
So far, all the examples in this chapter have run against a Rails application's development database, so you only needed to make sure that the development section of your config/database.yml file was set up correctly. Unit test code runs on your application's test database, so now you need to set up your test section as well. Your mywebapp_test database doesn't have to have any tables in it, but it must exist and be accessible to Rails.
When you generate a model with the generate script, Rails also generates a unit test script for the model in the test directory. It also creates a fixture, a YAML file containing test data to be loaded into the mywebapp_test database. This is the data against which your unit tests will run:
	./script/generate model User

	      exists app/models/

	      exists test/unit/

	      exists test/fixtures/

 	      create app/models/user.rb

	      create test/unit/user_test.rb

	      create test/fixtures/users.yml

	      create db/migrate

	      create db/migrate/001_create_users.rb
When you generate a controller with generate, Rails creates a functional test script for the controller:
	./script/generate users list

	      exists app/controllers/

	      exists app/helpers/

	      create app/views/users

	      exists test/functional/

	      create app/controllers/users_controller.rbcreate test/functional/users_controller_test.rb

	      create app/helpers/users_helper.rb

	      create app/views/users/list.rhtml
As you write code in the model and controller classes, you'll write corresponding tests in these files.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Using breakpoint in Your Web Application
Inhaltsvorschau
Your Rails application has a bug that you can't find using log messages. You need a heavy-duty debugging tool that lets you inspect the full state of your application at any given point.
The breakpoint library lets you stop the flow of code and drop into irb, an interactive Ruby session. Within irb you can inspect the variables local to the current scope, modify those variables, and resume execution of the normal flow of code. If you have ever spent hours trying to track down a bug by placing logging messages everywhere, you'll find that breakpoint gives you a much easier and more straightforward way to debug.
But how can you run an interactive console program from a web application? The answer is to have a console program running beforehand, listening for calls from the Rails server.
The first step is to run ./script/breakpointer on the command line. This command starts a server that listens over the network for breakpoint calls from the Rails server. Keep this program running in a terminal window: this is where the irb session will start up:
	$ ./script/breakpointer

	No connection to breakpoint service at druby://localhost:42531

	Tries to connect will be made every 2 seconds…
To trigger an irb session, you can call the breakpoint method anywhere you like from your Rails application—within a model, controller, or helper method. When execution reaches that point, processing of the incoming client request will stop, and an irb session will start in your terminal. When you quit the session, processing of the request will resume.
Here's an example. Let's say you've written the following controller, and you're having trouble modifying the name attribute of an Item object.
	class ItemsController < ApplicationController

	  def update

	    @item = Item.find(params[:id])

	    @item.value = '[default]'

	    @item.name = params[:name]

	    @item.save

	    render :text => 'Saved'

	  end

	end
You can put a breakpoint call in the Item class, like this:
	class Item < ActiveRecord::Base

	  attr_accessor :name, :value



	  def name=(name)

	    super

	    breakpoint

	  end

	end
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Chapter 16: Web Services and Distributed Programming
Inhaltsvorschau
Distributed programming is like network programming—only the audience is different. The point of network programming is to let a human control a computer across the network. The point of distributed programming is to let computers communicate between themselves.
Humans use networking software to get data and use algorithms they don't have on their own computers. With distributed programming, automated programs can get in on this action. The programs are (one hopes) designed for the ultimate benefit of humans, but an end user doesn't see the network usage or even neccessarily know that it's happening.
The simplest and most common form of distributed programming is the web service. Web services work on top of HTTP: they generally involve sending an HTTP request to a certain URL (possibly including an XML document), and getting a response in the form of another XML document. Rather than showing this document to an end user the way a web browser would, the web service client parses the XML response document and does something with it.
We start the chapter with a number of recipes that show how to provide and use web services. We include generic recipes like Recipe 16.3, and recipes for using specific, existing web services like Recipes 16.1, 16.6, and 16.9. The specific examples are useful in their own right, but they should also help you see what kind of features you should expose in your own web services.
There are three main approaches to web services: REST-style services, XML-RPC, and SOAP. You don't need any special tools to offer or use REST-style services. On the client end, you just need a scriptable web client (Recipe 14.1) and an XML parser (Recipes 11.2 and 11.3). On the server side, you just write a web application that knows how to generate XML (Recipe 11.9). We cover some REST philosophy while exploring useful services in Recipe 16.1 and Recipe 16.2.
REST is HTTP; XML-RPC and SOAP are protocols that run on top of HTTP. We've devoted several recipes to Ruby's SOAP client: Recipes 16.4 and 16.7 are the main ones. Ruby's standalone SOAP server is briefly covered in Recipe 16.5. Rails provides its own SOAP server (Recipe 15.18), which incidentally also acts as an XML-RPC server.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Searching for Books on Amazon
Inhaltsvorschau
You want to incorporate information about books or other cultural artifacts into your application.
Amazon.com exposes a web service that gives you access to all kinds of information on books, music, and other media. The third-party Ruby/ Amazon library provides a simple Ruby interface to the Amazon web service.
Here's a simple bit of code that searches for books with Ruby/Amazon, printing their new and used prices.
	require 'amazon/search'



	$AWS_KEY = 'Your AWS key goes here' # See below.



	def price_books(keyword)

	  req = Amazon::Search::Request.new($AWS_KEY)

	  req.keyword_search(keyword, 'books', Amazon::Search::LIGHT) do |product|



	    newp = product.our_price || 'Not available'

	    usedp = product.used_price || 'not available'

	    puts "#{product.product_name}: #{newp} new, #{usedp} used."

	  end

	end



	price_books('ruby cookbook')

	# Ruby Cookbook (Cookbooks (O'Reilly)): $31.49 new, not available used.

	# Rails Cookbook (Cookbooks (O'Reilly)): $25.19 new, not available used.

	# Ruby Ann's Down Home Trailer Park Cookbook: $10.85 new, $3.54 used.

	# Ruby's Low-Fat Soul-Food Cookbook: Not available new, $12.43 used.

	# …
To save bandwidth, this code asks Amazon for a "light" set of search results. The results won't include things like customer reviews.
What's going on here? In one sense, it doesn't matter. Ruby/Amazon gives us a Ruby method that somehow knows about books and their Amazon prices. It's getting its information from a database somewhere, and all we need to know is how to query that database.
In another sense, it matters a lot, because this is just one example of a REST-style web service. By looking under the cover of the Amazon web services, you can see how to use other REST-style services like the ones provided by Yahoo! and Flickr.
REST-style web services operate directly on top of HTTP. Each URL in a REST system designates a resource or a set of them. When you call keyword_search, Ruby/ Amazon retrieves a URL that looks something like this:
	http://xml.amazon.com/onca/xml3?KeywordSearch=ruby+cookbook&mode=books…
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Finding Photos on Flickr
Inhaltsvorschau
You want to use Ruby code to find freely reusable photos: perhaps to automatically illustrate a piece of text.
The Flickr photo-sharing web site has a huge number of photos and provides web services for searching them. Many of the photos are licensed under Creative Commons licenses, which give you permission to reuse the photos under various restrictions.
There are several Ruby bindings to Flickr's various web service APIs, but its REST API is so simple that I'm just going to use it directly. Given a tag name (like "elephants"), this code will find an appropriate picture, and return the URL to a thumbnail version of the picture.
First, a bit of setup. As with Amazon and Google, to use the Flickr API at all you'll need to sign up for an API key (see below for details).
	require 'open-uri'

	require 'rexml/document'

	require 'cgi'



	FLICKR_API_KEY = 'Your API key here'
The first method, flickr_call, sends a generic query to Flickr's REST web service. It doesn't do anything special: it just makes an HTTP GET request and parses the XML response.
	def flickr_call(method_name, arg_map={}.freeze)

	  args = arg_map.collect {|k,v| CGI.escape(k) + '=' + CGI.escape(v)}.join('&')

	  url = "http://www.flickr.com/services/rest/?api_key=%s&method=%s&%s" %

	    [FLICKR_API_KEY, method_name, args]

	    doc = REXML::Document.new(open(url).read)

	end
Now comes pick_a_photo, a method that uses flickr_call to invoke the flickr.photos.search web service method. That method returns a REXML Document object containing a <photo> element for each photo that matched the search criteria. I use XPath to grab the first <photo> element, and pass it into small_photo_url (defined below) to turn it into an image URL.
	def pick_a_photo(tag)

	  doc = flickr_call('flickr.photos.search', 'tags' => tag, 'license' => '4',

	                    'per_page' => '1')

	  photo = REXML::XPath.first(doc, '//photo')

	  small_photo_url(photo) if photo

	end
Finally, I'll define the method, small_photo_url. Given a <photo> element, it returns the URL to a smallish version of the appropriate Flickr photo.
	def small_photo_url(photo)

	 server, id, secret = ['server', 'id', 'secret'].collect do |field|

	   photo.attribute(field)

	 end

	 "http://static. 

flickr.com/#{server}/#{id}_#{secret}_m.jpg"

	end
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Writing an XML-RPC Client
Inhaltsvorschau
Credit: John-Mason Shackelford
You want to call a remote method through the XML-RPC web service protocol.
Use Michael Neumann's xmlrpc4r library, found in Ruby's standard library.
Here's the canonical simple XML-RPC example. Given a number, it looks up the name of a U.S. state in an alphabetic list:
	require 'xmlrpc/client'

	server = XMLRPC::Client.new2('http://betty.userland.com/RPC2')

	server.call('examples.getStateName', 5) # => "California"
XML-RPC is a language-independent solution for distributed systems that makes a simple alternative to SOAP (in fact, XML-RPC is an ancestor of SOAP). Although it's losing ground to SOAP and REST-style web services, XML-RPC is still used by many blogging engines and popular web services, due to its simplicity and relatively long history.
A XML-RPC request is sent to the server as a specially-formatted HTTP POST request, and the XML-RPC response is encoded in the HTTP response to that request. Since most firewalls allow HTTP traffic, this has the advantage (and disadvantage) that XML-RPC requests work through most firewalls. Since XML-RPC requests are POST requests, typical HTTP caching solutions (which only cache GETs) can't be used to speed up XML-RPC requests or save bandwidth.
An XML-RPC request consists of a standard set of HTTP headers, a simple XML document that encodes the name of a remote method to call, and the parameters to pass to that method. The xmlrpc4r library automatically converts between most XML-RPC data types and the corresponding Ruby data types, so you can treat XML-RPC calls almost like local method calls. The main exceptions are date and time objects. You can pass a Ruby Date or Time object into an XML-RPC method that expects a dateTime.iso8601 parameter, but a method that returns a date will always be represented as an instance of XMLRPC::DateTime.
Table 16-1 lists the supported data types of the request parameters and the response.
Table 16-1: Supported data types
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Writing a SOAP Client
Inhaltsvorschau
Credit: Kevin Marshall
You need to call a remote method through a SOAP-based web service.
Use the SOAP RPC Driver in the Ruby standard library.
This simple program prints a quote of the day. It uses the SOAP RPC Driver to connect to the SOAP web service at codingtheweb.com.
	require 'soap/rpc/driver'

	driver = SOAP::RPC::Driver.new(

	            'http://webservices.codingtheweb.com/bin/qotd',

	            'urn:xmethods-qotd')
Once the driver is set up, we define the web service method we want to call (getQuote). We can then call it like a normal Ruby method and display the result:
	driver.add_method('getQuote')



	puts driver.getQuote

	# The holy passion of Friendship is of so sweet and steady and

	# loyal and enduring a nature that it will last through a whole

	# lifetime, if not asked to lend money.

	# Mark Twain (1835 - 1910)
SOAP is a heavyweight protocol for web services, a distant descendant of XML-RPC. As with XML-RPC, a SOAP client sends an XML representation of a method call to a server, and gets back an XML representation of a return value. The whole process is more complex than XML-RPC, but Ruby's built-in SOAP library handles the low-level details for you, leaving you free to focus on using the results in your program.
There are only a few things you need to know to build useful SOAP clients (as I run through them, I'll build another SOAP client; this one is to get stock quotes):
  1. The location of the web service (known as the endpoint URL) and the namespace used by the service's documents.
    	require 'soap/rpc/driver'
    
    	driver = SOAP::RPC::Driver.new(
    
    	   'http://services.xmethods.net/soap/',        # The endpoint url
    
    	   'urn:xmethods-delayed-quotes')               # The namespace
  2. The name of the SOAP method you want to call, and the names of its parameters.
    	driver.add_method('getQuote', 'symbol')
    Behind the scenes, that call to add_method actually defines a new method on the SOAP::RPC::Driver object. The SOAP library uses metaprogramming to create custom Ruby methods that act like SOAP methods.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Writing a SOAP Server
Inhaltsvorschau
Credit: Kevin Marshall
You want to host a SOAP-based web service using a standalone server (that is, not as part of a Rails application).
Building your own SOAP server really only requires three simple steps:
  1. Subclass the SOAP::StandaloneServer class. In the constructor, register the methods you want to expose and the arguments they should take. Here we expose a method sayhelloto method that expects one parameter, username:
    	require 'soap/rpc/standaloneServer'
    
    
    
    	class MyServer < SOAP::RPC::StandaloneServer
    
    	  def initialize(*args)
    
    	    super
    
    	    add_method(self, 'sayhelloto', 'username')
    
    	  end
    
    	end
  2. Define the methods you exposed in step 1:
    	class MyServer
    
    	  def sayhelloto(username)
    
    	    "Hello, #{username}."
    
    	  end
    
    	end
  3. Finally, set up and start your server. Our example server runs on port 8888 on localhost. Its name is "CoolServer" and its namespace is "urn:mySoapServer":
    	server = MyServer.new('CoolServer','urn:mySoapServer','localhost',8888)
    
    	trap('INT') { server.shutdown }
    
    	server.start
    We trap interrupt signals so that we can stop our server from the command line.
We've now built a complete SOAP server. It uses the SOAP StandaloneServer and hosts one simple sayhelloto method that can be accessed at "http://localhost:8888/sayhelloto" with a namespace of "urn:mySoapServer".
To test your service, start your server in one Ruby session and then use the simple script below in another Ruby session to call the method it exposes:
	require 'soap/rpc/driver'

	driver = SOAP::RPC::Driver.new('http://localhost:8888/', 'urn:mySoapServer')

	driver.add_method('sayhelloto', 'username')

	driver.sayhelloto('Kevin')                              # => "Hello, Kevin."
  • Recipe 15.18, "Exposing Web Services on Your Web Site," shows how to use the XML-RPC/ SOAP server that comes with Rails
  • For information on building web service clients, see Recipes 16.2 through 16.3, 16.4 and 16.7.
  • Ruby on Rails by Bruce A. Tate and Curt Hibbs (O'Reilly)
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Searching the Web with Google's SOAP Service
Inhaltsvorschau
You want to use Google's web services to perform searches and grab their results within your Ruby application.
Google exposes a SOAP API to its search functionality, and some other miscellaneous methods like spellcheck. Call these methods with the SOAP client that comes with Ruby's standard library:
	$KCODE = 'u' # This lets us parse UTF characters

	require 'soap/wsdlDriver'



	class Google

	  @@key = 'JW/JqyXMzCsv7k/dxqR9E9HF+jiSgbDL'

	# Get a key at http://www.google.com/apis/

	  @@driver = SOAP::WSDLDriverFactory.

	    new('http://api.google.com/GoogleSearch.wsdl').create_rpc_driver



	  def self.search(query, options={})

	     @@driver.doGoogleSearch(

	       @@key,

	       query,

	       options[:offset] || 0,

	       options[:limit] || 10,           # Note that this value cannot exceed 10

	       options[:filter] || true,

	       options[:restricts] || ' ',

	       options[:safe_search] || false,

	       options[:lr] || ' ',

	       options[:ie] || ' ',

	       options[:oe] || ' '

	     )

	   end



	   def self.count(query, options={})

	     search(query, options).estimatedTotalResultsCount

	   end



	  def self.spell(phrase)

	    @@driver.doSpellingSuggestion(@@key, phrase)

	  end

	end
Here it is in action:
 

Google.count "Ruby Cookbook site:oreilly.com"

	# => 368



	results =  

Google.search "Ruby Cookbook site:oreilly.com", :limit => 7

	results.resultElements.size

	# => 7



	results.resultElements.first["title"]

	# => "oreilly.com -- Online Catalog: <b>Ruby Cookbook</b>…"



	results.resultElements.first["URL"]

	# => "http://www.oreilly.com/catalog/rubyckbk/"



	results.resultElements.first["snippet"]

	# => "The <b>Ruby Cookbook</b> is a new addition to …"



	 

Google.spell "tis is te centence"

	# => "this is the sentence"
Each of the options defined in Google.search corresponds to an option in the Google search API.
Name
Description
key
Unique key provided when you sign up with Google's web services.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Using a WSDL File to Make SOAP Calls Easier
Inhaltsvorschau
Credit: Kevin Marshall
You need to create a client for a SOAP-based web service, but you don't want to type out the definitions for all the SOAP methods you'll be calling.
Most web services provide a WSDL file: a machine-readable description of the methods they offer. Ruby's SOAP WSDL Driver can parse a WSDL file and make the appropriate methods available automatically.
This code uses the xmethods.com SOAP web service to get a stock price. In Recipe 16.7, we defined the getQuote method manually. Here, its name and signature are loaded from a hosted WSDL file. You still have to know that the method is called getQuote and that it takes one string, but you don't have to write any code telling Ruby this.
	require 'soap/wsdlDriver'

	wsdl = 'http://services.xmethods.net/soap/urn:xmethods-delayed-quotes.wsdl'

	driver = SOAP::WSDLDriverFactory.new(wsdl).create_rpc_driver



	puts "Stock price: %.2f" % driver.getQuote('TR')

	# Stock price: 28.78
According to the World Wide Web Consortium (W3), "WSDL service definitions provide documentation for distributed systems and serve as a recipe for automating the details involved in applications communication."
What this means to you is that you don't have to tell Ruby which methods a web service provides, and what arguments it expects. If you feed a WSDL file in to the Driver Factory, Ruby will give you a Driver object with all the methods already defined.
There are only a few things you need to know to build useful SOAP clients with a WSDL file. I'll illustrate with some code that performs a Google search and prints out the results.
  1. Start with the URL to the WSDL file:
    	require 'soap/wsdlDriver'
    
    	wsdl = 'http://api.google.com/GoogleSearch.wsdl'
    
    	driver = SOAP::WSDLDriverFactory.new(wsdl).create_rpc_driver
  2. Next you need the name of the SOAP method you want to call, and the expected types of its parameters:
    	my_google_key = 'get yours from https://www.google.com/accounts'
    
    	my_query = 'WSDL Ruby'
    
    	XSD::Charset.encoding = 'UTF8'
    
    	result = driver.doGoogleSearch(my_google_key, my_query, 0, 10, false,
    
    	                               '', false, '', '', '')
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Charging a Credit Card
Inhaltsvorschau
You want to charge a credit card from within your Ruby application.
To charge credit cards online, you need an account with a credit card merchant. Although there are many to choose from, Authorize.Net is one of the best and most widely used. The payment library encapsulates the logic of making a credit card payments with Authorize.Net, and soon it will support other gateways as well. It's available as the payment gem.
	require 'rubygems'

	require 'payment/authorize_net'

	

	transaction = Payment::AuthorizeNet.new(

	  :login           => 'username',

	  :transaction_key => 'my_key',

	  :amount          => '49.95',

	  :card_number     => '4012888818888',

	  :expiration      => '0310',

	  :first_name      => 'John',

	  :last_name       => 'Doe'

	)
The submit method sends a payment request. If there's a problem with your payment (probably due to an invalid credit card), the submit method will raise a Payment::PaymentError:
	begin

	  transaction.submit

	  puts "Card processed successfully: #{transaction.authorization}"

	rescue Payment::PaymentError

	  puts "Card was rejected: #{transaction.error_message}"

	end

	# Card was rejected: The merchant login ID or password is invalid

	# or the account is inactive.
Some of the information sent during initialization of the Payment::AuthorizeNet class represent your account with Authorize.Net, and will never change (at least, not for the lifetime of the account). You can store this information in a YAML file called .payment.yml in your home directory, and have the payment library load it automatically. A .payment.yml file might look like this:
	login: username

	transaction_key: my_key
That way you don't have to hardcode login and transaction_key within your Ruby code.
If you're using the payment library from within a Rails application, you might want to put your YAML hash in the config directory with other configuration files, instead of in your home directory. You can override the location for the defaults file by specifying the :prefs key while initializing the object:
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Finding the Cost to Ship Packages via UPS or FedEx
Inhaltsvorschau
You want to calculate the cost to ship any item with FedEx or UPS. This is useful if you're running an online store.
FedEx and UPS provide web services that can query information on pricing as well as retrieve shipping labels. The logic for using these services has been encapsulated within the shipping gem:
	require 'rubygems'

	require 'shipping'



	ship = Shipping::Base.new(

	  :fedex_url => 'https://gatewaybeta.fedex.com/GatewayDC',

	  :fedex_account => '123456789',

	  :fedex_meter => '387878',



	  :ups_account => '7B4F74E3075AEEFF',

	  :ups_user => 'username',

	  :ups_password => 'password',



	  :sender_zip => 10001                   # It's shipped from Manhattan.

	)



	ship.weight = 2                             # It weighs two pounds.

	ship.city = 'Portland'

	ship.state = 'OR'

	ship.zip = 97202



	ship.ups.price                              # => 8.77

	ship.fedex.price                            # => 5.49

	ship.ups.valid_address?                     # => true
If you have a UPS account or a FedEx account, but not both, you can omit the account information you don't have, and instantiate a Shipping::UPS or a Shipping::FedEx object.
You can either specify your account information during the initialization of the object (as above) or in a YAML hash. It's similar to the payment library described in Recipe 16.8. If you choose to use the YAML hash, you can specify the account information in a file called .shipping.yml within the home directory of the user running the Ruby program:
	fedex_url: https://gatewaybeta.fedex.com/GatewayDC

	fedex_account: 1234556

	fedex_meter: 387878



	ups_account: 7B4F74E3075AEEFF

	ups_user: username

	ups_password: password
But your directory is not a good place to keep a file being used by a Rails application. Here's how to move the .shipping file into a Rails application:
	ship = Shipping:: 

FedEx.new(:prefs => "#{RAILS_ROOT}/config/shipping.yml")

	ship.sender_zip = 10001

	ship.zip = 97202

	ship.state = 'OR'

	ship.weight = 2



	ship.price > ship.discount_price                    # => true
Notice the use of ship.discount_price to find the discounted price; if you have an account with FedEx or UPS, you might be eligible for discounts.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Sharing a Hash Between Any Number of Computers
Inhaltsvorschau
Credit: James Edward Gray II
You want to easily share some application data with remote programs. Your needs are as trivial as, "What if all the computers could share this hash?"
Ruby's built-in DRb library can share Ruby objects across a network. Here's a simple hash server:
	#!/usr/local/ruby -w

	# 

drb_hash_server.rb

	require 'drb'



	# Start up DRb with a URI and a hash to share

	shared_hash = {:server => 'Some data set by the server' }

	DRb.start_service('druby://127.0.0.1:61676', shared_hash)

	puts 'Listening for connection…'

	DRb.thread.join # Wait on DRb thread to exit…
Run this server in one Ruby session, and then you can run a client in another:
	require 'drb'



	# Prep DRb

	DRb.start_service

	# Fetch the shared object

	shared_data = DRbObject.new_with_uri('druby://127.0.0.1:61676')



	# Add to the Hash

	shared_data[:client] = 'Some data set by the client'

	shared_data.each do |key, value|

	  puts "#{key} => #{value}"

	end

	# client => Some data set by the client

	# server => Some data set by the server
If this looks like magic, that's the point. DRb hides the complexity of distributed programming. There are some complications (covered in later recipes), but for the most part DRb simply makes remote objects look like local objects.
The solution given above may meet your needs if you're working with a single server and client on a trusted network, but applications aren't always that simple. Issues like thread-safety and security may force you to find a more robust solution. Luckily, that doesn't require too much more work.
Let's take thread-safety first. Behind the scenes, a DRb server handles each client connection in a separate Ruby thread. Ruby's Hash class is not automatically thread-safe, so we need to do a little extra work before we can reliably share a hash between multiple concurrent users.
Here's a library that uses delegation to implement a thread-safe hash. A ThreadsafeHash object delegates all its method calls to an underlying Hash object, but it uses a Mutex to ensure that only one thread (or DRb client) can have access to the hash at a time.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Implementing a Distributed Queue
Inhaltsvorschau
Credit: James Edward Gray II
You want to use a central server as a workhorse, queueing up requests from remote clients and handling them one at a time.
Here's a method that shares a Queue object with clients. Clients put job objects into the queue, and the server handles them by yielding them to a code block. #!/usr/bin/ruby
	#!/usr/bin/ruby

	# queue_server.rb



	require 'thread'           # For Ruby's thread-safe Queue

	require 'drb'



	$SAFE = 1                  # Minimum acceptable paranoia level when sharing code!



	def run_queue(url='druby://127.0.0.1:61676')

	  queue = Queue.new        # Containing the jobs to be processed



	  # Start up DRb with URI and object to share

	  DRb.start_service(url, queue)

	  puts 'Listening for connection…'

	  while job = queue.deq

	    yield job

	  end

	end
Have your server call run_queue, passing in a code block that handles a single job. Every time one of your clients puts a job into the server queue, the server passes the job into the code block. Here's a sample code block that can handle a fast-running job ("Report") or a slow-running job ("Process"):
	run_queue do |job|

	  case job['request']

	  when 'Report'

	    puts "Reporting for #{job['from']}… Done."

	  when 'Process'

	    puts "Processing for #{job['from']}…"

	    sleep 3          # Simulate real work

	    puts 'Processing complete.'

	  end

	end
If we get a couple of clients sending in requests, output might look like this:
	$ ruby queue_server.rb

	Listening for connection…



	Processing for Client 1…

	Processing complete.

	Processing for Client 2…

	Processing complete.

	Reporting for Client 1… Done.

	Reporting for Client 2… Done.

	Processing for Client 1…

	Processing complete.

	Reporting for Client 2… Done.

	…
A client for the queue server defined in the Solution simply needs to connect to the DRB server and add a mix of "Report" and "Process" jobs to the queue. Here's a client that connects to the DRb server and adds 20 jobs to the queue at random:
	#!/usr/bin/ruby

	# queue_client.rb



	require 'thread'

	require 'drb'



	# Get a unique name for this client

	NAME = ARGV.shift or raise "Usage: #{File.basename($0)} CLIENT_NAME"



	DRb.start_service

	queue = DRbObject.new_with_uri("druby://127.0.0.1:61676")



	20.times do

	  queue.enq('request' => ['Report', 'Process'][rand(2)], 'from' => NAME)

	  sleep 1 # simulating network delays

	end
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Creating a Shared "Whiteboard"
Inhaltsvorschau
Credit: James Edward Gray II
You want to create the network equivalent of a whiteboard. Remote programs can place Ruby objects up on the board, examine objects on the board, or remove objects from the board.
You could just use a synchronized hash (as in Recipe 16.10), but Rinda provides a data structure called a TupleSpace that is optimized for distributed programming. It works well when you have some clients putting data on the whiteboard, and other clients processing the data and taking it down.
Let's create an application that lets clients on different parts of the network translate each others' sentences, and builds a translation dictionary as they work.
It's easier to see the architecture of the server if you see the clients first, so here's a client that adds some English sentences to a shared TupleSpace:
	#!/usr/bin/ruby -w

	# english_client.rb

	require 'drb'

	require 'rinda/tuplespace'



	# Connect to the TupleSpace…

	DRb.start_service

	tuplespace = Rinda::TupleSpaceProxy.new(

	  DRbObject.new_with_uri('druby://127.0.0.1:61676')

	)
The English client's job is to split English sentences into words and to add each sentence to the whiteboard as a tuple: [unique id, language, words].
	counter = 0

	DATA.each_line do |line|

	  tuplespace.write([(counter += 1), 'English', line.strip.split])

	end



	__END__

	Ruby programmers have more fun

	Ruby gurus are obsessed with ducks

	Ruby programmers are happy programmers
Here's a second client. It creates a loop that continually reads all the English sentences from the TupleSpace and puts up word-for-word translations into Pig Latin. It uses Tuplespace#read to read English-language tuples off the whiteboard without removing them.
	require 'drb'

	require 'rinda/tuplespace'

	require 'set'



	DRb.start_service

	tuplespace = Rinda::TupleSpaceProxy.new(

	  DRbObject.new_with_uri('druby://127.0.0.1:61676')

	)



	# Track of the IDs of the sentences we've translated

	translated = Set.new



	# Continually read English sentences off of the board.

	while english = tuplespace.read([Numeric, 'English', Array])

	  # Skip anything we've already translated.

	  next if translated.member? english.first

	  translated << english.first



	  # Translate English to Pig Latin.

	  pig_latin = english.last.map do |word|

	   if word =~ /^[aeiou]/i

	      "#{word}way"

	    elsif word =~ /^([^aeiouy]+)(.+)$/i

	      "#{$2}#{$1.downcase}ay"

	    end

	  end



	  # Write the Pig Latin translation back onto the board

  	  tuplespace.write([english.first, 'Pig Latin', pig_latin])

	end
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Securing DRb Services with Access Control Lists
Inhaltsvorschau
Credit: James Edward Gray II
You want to keep everybody in the world (literally!) from having access to your DRb service. Instead you want to control which hosts can, and cannot, connect.
Here's the simple shared hash from Recipe 16.10, only this time it's locked down with DRb's ACL (access control list) class:
	#!/usr/bin/ruby

	# acl_hash_server.rb



	require 'drb'

	require 'drb/acl'



	# Setup the security--remember to call before DRb.start_service()

	DRb.install_acl(ACL.new(%w{ deny all

	                            allow 192.168.1.*

	                            allow 127.0.0.1 } ) )

	# Start up DRb with a URI and a hash to share

	shared_hash = {:server => 'Some data set by the server' }

	DRb.start_service("druby://127.0.0.1:61676", shared_hash)

	puts 'Listening for connection…'

	DRb.thread.join # Wait on DRb thread to exit…
If you bind your DRb server to localhost, it'll only be accessible to other Ruby processes on your computer. That's not very distributed. But if you bind your DRb server to some other hostname, anyone on your local network (if you've got a local network) or anyone on the Internet at large will be able to share your Ruby objects. You're probably not feeling that generous.
DRb's ACL class provides simple white/blacklist security similar to that used by the Unix /etc/hosts.allow and /etc/hosts.deny files. The ACL constructor takes an array of strings. The first string of a pair is always "allow" or "deny", and it's followed by the address or addresses to allow or deny access.
String addresses can include wildcards ("**"), as shown in the solution, to allow or deny an entire range of addresses. The ACL class also understands the term "all," and your first address should be either "deny all" or (less likely) "allow all". Subsequent entries can relax or restrict access, as needed.
In the Solution above, the default is to deny access. Exceptions are carved out afterwards for anyone on the local IP network (192.168.1.**) and anyone on the same host as the server itself (127.0.0.1). A public DRb server might allow access by default, and deny access only to troublesome client IPs.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Automatically Discovering DRb Services with Rinda
Inhaltsvorschau
Credit: James Edward Gray II
You want to distribute Ruby code across your local network without hardcoding the clients with the addresses of the servers.
Using Ruby's standard Rinda library, it's easy to provide zero-configuration networking for clients and services. With Rinda, machines can discover DRb services without providing any addresses. All you need is a running RingServer on the local network:
	#!/usr/bin/ruby

	# rinda_server.rb



	require 'rinda/ring'       # for RingServer

	require 'rinda/tuplespace' # for TupleSpace



	DRb.start_service



	# Create a TupleSpace to hold named services, and start running.

	Rinda::RingServer.new(Rinda::TupleSpace.new)



	DRb.thread.join
The RingServer provides automatic service detection for DRb servers. Any machine on your local network can find the local RingServer without knowing its address. Once it's found the server, a client can look up services and use them, not having to know the addresses of the DRb servers that host them.
To find the Rinda server, a client broadcasts a UDP packet asking for the location of a RingServer. All computers on the local network will get this packet, and if a computer is running a RingServer, it will respond with its address. A server can use the RingServer to register services; a client can use the RingServer to look up services.
A RingServer object keeps a service listing in a shared TupleSpace (see Recipe 16.12). Each service has a corresponding tuple with four members:
  • The literal symbol :name, which indicates that the tuple is an entry in the RingServer namespace.
  • The symbol of a Ruby class, indicating the type of the service.
  • The DRbObject shared by the service.
  • A string description of the service.
By retrieving this TupleSpace remotely, you can look up services as tuples and advertise your own services. Let's advertise an object (a simple TupleSpace) through the RingServer under the name :TupleSpace:
	#!/usr/bin/ruby

	# share_a_tuplespace.rb



	require ' 

rinda/ring'        # for RingFinger and SimpleRenewer

	require ' 

rinda/tuplespace'  # for TupleSpace



	DRb.start_service

	ring_server = Rinda::RingFinger.primary



	# Register our TupleSpace service with the RingServer

	ring_server.write( [:name, :TupleSpace, Rinda::TupleSpace.new, 'Tuple Space'],

	                   Rinda::SimpleRenewer.new )

	

	DRb.thread.join
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Proxying Objects That Can't Be Distributed
Inhaltsvorschau
Credit: James Edward Gray II
You want to allow classes to connect to your DRb server, without giving the server access to the class definition. Perhaps you've given clients an API to implement, and you don't want to make everyone send you the source to their implementations just so they can connect to the server.
…OR…
You have some code that is tied to local resources: database connections, log files, or even just the closure aspect of Ruby's blocks. You want this code to interact with a DRb server, but it must be run locally.
…OR…
You want to send an object to a DRb server, perhaps as a parameter to a method; but you want the server to notice changes to that object as your local code modifies it.
Rather than sending an object to the server, you can ask DRb to send a proxy instead. When the server acts on the proxy, a description of the act will be sent across the network. The client end will actually perform the action. In effect, you've partially switched the roles of the client and the server.
You can set up a proxy in two simple steps. First, make sure your client code includes the following line before it interacts with any server objects:
	DRb.start_service # The client needs to be a DRb service too.
That's generally just a good habit to get into with DRb client code, because it allows DRb to magically support some constructs (like Ruby's blocks) by sending a proxy object when necessary. If you're intentionally trying to send a proxy, it becomes essential.
As long as your client is a DRb service of its own, you can proxy all objects made from a specific class or individual objects by including the DRbUndumped module:
	class MyLocalClass

	  include DRbUndumped # The magic line. All objects of this type are proxied.

	  # …

	end



	# … OR …



	my_local_object.extend DRbUndumped # Proxy just this object.
Under normal circumstances, DRb is very simple. A method call is packaged up (using Marshal) as a target object, method name, and some arguments. The resulting object is sent over the wire to the server, where it's executed. The important thing to notice is that the server receives copies of the original arguments.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Storing Data on Distributed RAM with MemCached
Inhaltsvorschau
Credit: Ben Bleything with Michael Granger
You need a lightweight, persistent storage space, and you have systems on your network that have unused RAM.
memcached provides a distributed in-memory cache. When used with a Ruby client library, it can be used to store almost any Ruby object. See the Discussion section below for more information, and details of where to get memcached.
In this example, we'll use Michael Granger's Ruby-MemCache library, available as the Ruby-MemCache gem.
Assume you have a memcached server running on the machine at IP address 10.0.1.201. You can use the memcache gem to access the cache as though it were a local hash. This Ruby code will store a string in the remote cache:
	require 'rubygems'

	require 'memcache'



	MC = MemCache.new '10.0.1.201'



	MC[:test] = 'This string lives in memcached!'
The string has been placed in your memcached with the key :test. You can fetch it from a different Ruby session:
	require 'rubygems'

	require 'memcache'



	MC = MemCache.new '10.0.1.201'



	MC[:test]                         # => "This string lives in memcached!"
You can also place more complex objects in memcached. In fact, any object that can be serialized with Marshal.dump can be placed in memcached. Here we store and retrieve a hash:
	hash = {

	  :roses => 'are red',

	  :violets => 'are blue'

	}



	MC[:my_hash] = hash

	MC[:my_hash][:roses]              # => "are red"
memcached was originally designed to alleviate pressure on the database servers for LiveJournal.com. For more information about how memcached can be used for this kind of purpose, see Recipe 16.17.
memcached provides a lightweight, distributed cache space where the cache is held in RAM. This makes the cache extremely fast, and it never blocks on disk I/O. When effectively deployed, memcached can significantly reduce the load on your database servers by farming out storage to unused RAM on other machines.
To start using memcached, you'll need to download the server (see below). You can install it from source, or get it via most *nix packaging systems.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Caching Expensive Results with MemCached
Inhaltsvorschau
Credit: Michael Granger with Ben Bleything
You want to transparently cache the results of expensive operations, so that code that triggers the operations doesn't need to know how to use the cache. The memcached program, described in Recipe 16.16, lets you use other machines' RAM to store key-value pairs. The question is how to hide the use of this cache from the rest of your code.
If you have the luxury of designing your own implementation of the expensive operation, you can design in transparent caching from the beginning. The following code defines a get method that delegates to expensive_get if it can't find an appropriate value in the cache. In this case, the expensive operation that gets cached is the (relatively inexpensive, actually) string reversal operation:
	require 'rubygems'

	require 'memcache'



	class DataLayer

	

	  def initialize(*cache_servers)

	    @cache = MemCache.new(*cache_servers)

	  end



	  def get(key)

	    @cache[key] ||= expensive_get(key)

	  end

	 alias_method :[], :get



	  protected

	  def expensive_get(key)

	    # …do expensive fetch of data for 'key'

	    puts "Fetching expensive value for #{key}"

	    key.to_s.reverse

	  end

	end
Assuming you've got a memcached server running on your local machine, you can use this DataLayer as a way to cache the reversed versions of strings:
	layer = DataLayer.new( 'localhost:11211' )



	3.times do

	  puts "Data for 'foo': #{layer['foo']}"

	end

	# Fetching expensive value for foo

	# Data for 'foo': oof

	# Data for 'foo': oof
That's the easy case. But you don't always get the opportunity to define a data layer from scratch. If you want to add memcaching to an existing data layer, you can create a caching strategy and add it to your existing classes as a mixin.
Here's a data layer, already written, that has no caching:
	class MyDataLayer

	  def get(key)

	    puts "Getting value for #{key} from data layer"

	    return key.to_s.reverse

	  end

	end
The data layer doesn't know about the cache, so all of its operations are expensive. In this instance, it's reversing a string every time you ask for it:
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
A Remote-Controlled Jukebox
Inhaltsvorschau
What if you had a jukebox on your main computer that played random or selected items from your music collection? What if you could search your music collection and add items to the jukebox queue from a laptop in another room of the house?
Ruby can help you realize this super-geek dream—the software part, anyway. In this recipe, I'll show you how to write a jukebox server that can be programmed from any computer on the local network.
The jukebox will consist of a client and a server. The server broadcasts its location to a nearby Rinda server so clients on the local network can find it without knowing the address. The client will look up the server with Rinda and then communicate with it via DRb.
What features should the jukebox have? When there are no clients interfering with its business, the server will pick random songs from a predefined playlist and play them. It will call out to external Unix programs to play songs on the local computer's audio system (if you have a way of broadcasting songs through streaming audio, say, an IceCast server, it could use that instead).
A client can query the jukebox, stop or restart it, or request that a particular song be played. The jukebox will keep requests in a queue. Once it plays all the requests, it will resume playing songs at random.
Since we'll be running subprocesses to access the sound card on the computer that runs the jukebox, the Jukebox object can't be distributed to another machine. Instead, we need to proxy it with DRbUndumped.
The first thing we need to do is start a RingServer somewhere on our local network. Here's a reprint of the RingServer program from Recipe 16.14:
	#!/usr/bin/ruby

	# rinda_server.rb



	require 'rinda/ring'          # for RingServer

	require 'rinda/tuplespace'    # for TupleSpace



	DRb.start_service



	# Create a TupleSpace to hold named services, and start running.

	Rinda::RingServer.new(Rinda::TupleSpace.new)



	DRb.thread.join
Here's the jukebox server file. First, we'll define the Jukebox server class, and set up its basic behavior: to play its queue and pick randomly when the queue is empty.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Chapter 17: Testing, Debugging, Optimizing, and Documenting
Inhaltsvorschau
The recipes in previous chapters focus on writing code to do what you want. This chapter focuses on verifying that your code really works, and on fixing it when it breaks. We start off simple and move to more advanced debugging techniques.
What happens when your program has a bug? The best-case scenario is that you discover the bug before it affects anyone, including other developers. That's the goal of unit tests (Recipe 17.7). Ruby and the Ruby community promote a philosophy of writing automated tests as (or even before) you write the corresponding functionality. At every stage of development, you know that your program works, and if you make a change that breaks something, you know about it immediately. These tests can replace much boring manual testing and bug hunting.
Suppose a bug slips past your tests, and you only discover it in production. How's it going to manifest itself? If you're lucky, you'll see an exception: a notification from some piece of Ruby code that something is wrong.
Exceptions interrupt the normal flow of execution, and, if not handled, will crash the program. The good news is that they give you a place in the code to start debugging. It's worse if a bug doesn't cause an exception, because you'll only notice its byproducts: corrupt data or even security violations. We show code for handling exceptions (Recipes 17.3 and 17.4) and for creating your own (Recipe 17.2).
Successful debugging means reproducing the bug in an environment where you can poke at it. This may mean dropping from a running program into an irb session (Recipe 17.10), or it may be as simple as adding diagnostic messages that make the program show its work (Recipe 17.1).
Even a program that has no noticeable bugs may run too slowly or use too many resources. Ruby provides two tools for doing performance optimization: a profiler (Recipe 17.12) and a benchmarking suite (Recipe 17.13). It's easy to create your own analysis tools by writing a trace function that hooks into the Ruby interpreter as it runs. The call graph tracker presented at chapter's end (Recipe 17.15) exploits this feature.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Running Code Only in Debug Mode
Inhaltsvorschau
You want to print out debugging messages or run some sanity-checking code, but only while you're developing your application;, not when you're running it in production.
Run the code only if the global variable $DEBUG is true. You can trigger debug mode by passing in the --debug switch to the Ruby interpreter, or you can set the variable $DEBUG to true within your code.
Here's a Ruby program to divide two random numbers. It contains a trivial bug. It usually runs to completion, but sometimes it crashes. A line of debug code has been added to give some more visibility into the internal workings of the program:
	#!/usr/bin/env ruby

	# divide.rb

	numerator = rand(100)

	denominator = rand(10)

	$stderr.puts "Dividing #{numerator} by #{denominator}" if $DEBUG

	puts numerator / denominator
When run with the --debug flag, the debug message is printed to standard error:
	$ ./divide.rb --debug

	Dividing 64 by 9

	7



	$ ./divide.rb --debug

	Dividing 93 by 2

	46



	$ ./divide.rb --debug

	Dividing 54 by 0

	Exception 'ZeroDivisionError' at divide_buggy.rb:6 - divided by 0

	divide_buggy.rb:6:in '/': divided by 0 (ZeroDivisionError)

	        from divide_buggy.rb:6
Once the bug is fixed, you can go back to running the script normally, and the debug message won't show up:
	$ ./divide.rb

	24
This is a common technique when a "real" debugger is too much trouble. It's usually used to send debug messages to standard error, but you can put any code at all within a $DEBUG conditional. For instance, many Ruby libraries have their own "verbose", " debug level", or " debug mode" settings: you can choose to set these other variables appropriately only when $DEBUG is true.
	require 'fileutils'

	FileUtils.cp('source', 'destination', $DEBUG)
If your code is running deep within a framework, you may not have immediate access to the standard error stream of the process. You can always have your debug code write to a temporary logfile, and monitor the file.
Use of $DEBUG costs a little speed, but except in tight loops it's not noticeable. At the cost of a little more speed, you can save yourself some typing by defining convenience methods like this one:
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Raising an Exception
Inhaltsvorschau
Credit: Steve Arneil
An error has occurred and your code can't keep running. You want to indicate the error and let some other piece of code handle it.
Raise an exception by calling the Kernel#raise method with a description of the error. Calling the raise method interrupts the flow of execution.
The following method raises an exception whenever it's called. Its second message will never be printed:
	def raise_exception

	  puts 'I am before the raise.'

	  raise 'An error has occurred.'

	  puts 'I am after the raise.'

	end



	raise_exception

	# I am before the raise.

	# RuntimeError: An error has occurred
Here's a method, inverse, that returns the inverse of a number x. It does some basic error checking by raising an exception unless x is a number:
	def inverse(x)

	  raise "Argument is not numeric" unless x.is_a? Numeric

	  1.0 / x

	end
When you pass in a reasonable value of x, all is well:
	inverse(2)                                      # => 0.5
When x is not a number, the method raises an exception:
	inverse('not a number')

	# RuntimeError: Argument is not numeric
An exception is an object, and the Kernel#raise method creates an instance of an exception class. By default, Kernel#raise creates an exception of RuntimeError class, which is a subclass of StandardError. This in turn is a subclass of Exception, the superclass of all exception classes. You can list all the standard exception classes by starting a Ruby session and executing code like this:
	ObjectSpace.each_object(Class) do |x|

	  puts x if x.ancestors.member? Exception

	end
This variant lists only the better-known exception classes:
	ObjectSpace.each_object(Class) { |x| puts x if x.name =~ /Error$/ }

	# SystemStackError

	# LocalJumpError

	# EOFError

	# IOError

	# RegexpError

	# …
To raise an exception of a specific class, you can pass in the class name as an argument to raise. RuntimeError is kind of generic for the inverse method's check against x. The problem is there is actually a problem with one of the arguments passed into the method. A more aptly named exception class for that check would be
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Handling an Exception
Inhaltsvorschau
Credit: Steve Arneil
You want to handle or recover from a raised exception.
Rescue the exception with a begin/rescue block. The code you put into the rescue clause should handle the exception and allow the program to continue executing.
This code demonstrates the rescue clause:
	def raise_and_rescue

	  begin

	    puts 'I am before the raise.'

	    raise 'An error has occurred.'

	    puts 'I am after the raise.'

	  rescue

	    puts 'I am rescued!'

	  end

	  puts 'I am after the begin block.'

	end



	raise_and_rescue

	# I am before the raise.

	# I am rescued!

	# I am after the begin block.
The exception doesn't stop the program from running to completion, but the code that was interrupted by the exception never gets run. Once the exception is handled, execution continues immediately after the begin block that spawned it.
You can handle an exception with a rescue block if you know how to recover from the exception, if you want to display it in a nonstandard way, or if you know that the exception is not really a problem. You can solve the problem, present it to the end user, or just ignore it and forge ahead.
By default, a rescue clause rescues exceptions of class StandardError or its subclasses. Mentioning a specific class in a rescue statement will make it rescue exceptions of that class and its subclasses.
Here's a method, do_it, that calls the Kernel#eval method to run some Ruby code passed to it. If the code cannot be run (because it's not valid Ruby), eval raises an exception—a SyntaxError. This exception is not a subclass of StandardError; it's a subclass of ScriptError, which is a subclass of Exception.
	def do_it(code)

	  eval(code)

	rescue

	  puts "Cannot do it!"

	end



	do_it('puts 1 + 1')

	# 2



	do_it('puts 1 +')

	# SyntaxError: (eval):1:in 'do_it': compile error
That rescue block never gets called because SyntaxError is not a subclass of StandardError. We need to tell our rescue block to rescue us from SyntaxError, or else from one of its superclasses, ScriptError
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Rerunning After an Exception
Inhaltsvorschau
Credit: Steve Arneil
You want to rerun some code that raised an exception, having (hopefully) fixed the problem that caused it in the first place.
Retry the code that failed by executing a retry statement within a rescue clause of a code block. retry reruns the block from the beginning.
Here's a demonstration of the retry statement. The first time the code block runs, it raises an exception. The exception is rescued, the problem is "fixed," and the code runs to completion the second time:
	def rescue_and_retry

	  error_fixed = false

	  begin

	    puts 'I am before the raise in the begin block.'

	    raise 'An error has occurred!' unless error_fixed

	    puts 'I am after the raise in the begin block.'

	  rescue

	    puts 'An exception was thrown! 

Retrying…'

		error_fixed = true

		retry

	  end

	  puts 'I am after the begin block.'

	end

	rescue_and_retry

	# I am before the raise in the begin block.

	# An exception was thrown!  

Retrying…

	# I am before the raise in the begin block.

	# I am after the raise in the begin block.

	# I am after the begin block.
Here's a method, check_connection, that checks if you are connected to the Internet. It will try to connect to a url up to max_tries times. This method uses a retry clause to retry connecting until it successfully completes a connection, or until it runs out of tries:
	require 'open-uri'



	def check_connection(max_tries=2, url='http://www.ruby-lang.org/')

	  tries = 0

	  begin

	    tries += 1

	    puts 'Checking connection…'

	    open(url) { puts 'Connection OK.' }

	  rescue Exception

	    puts 'Connection not OK!'

	    retry unless tries >= max_tries

	  end

	end



	check_connection

	# Checking connection…

	# Connection OK.



	check_connection(2, 'http://this.is.a.fake.url/')

	# Checking connection…

	# Connection not OK!

	# Checking connection…

	# Connection not OK!
  • Recipe 17.2, "Raising an Exception"
  • Recipe 17.3, "Handling an Exception"
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Adding Logging to Your Application
Inhaltsvorschau
You want to make your application log events or diagnostic data to a file or stream. You want verbose logging when your application is in development, and more taciturn logging when in production.
Use the logger library in the Ruby standard library. Use its Logger class to send logging data to a file or other output stream.
In most cases, you'll share a single Logger object throughout your application, as a global variable or module constant:
	require ' 

logger'

	$LOG = Logger.new($stderr)
You can then call the instance methods of Logger to send messages to the log at various levels of severity. From least to most severe, the instance methods are Logger#debug, Logger#info, Logger#warn, Logger#error, and Logger#fatal.
This code uses the application's logger to print a debugging message, and (at a higher severity) as part of error-handling code.
	def divide(numerator, denominator)

	  $LOG.debug("Numerator: #{numerator}, denominator #{denominator}")

	  begin

	    result = numerator / denominator

	  rescue Exception => e

	    $LOG.error "Error in division!: #{e}"

	    result = nil

	  end

	  return result

	end



	divide(10, 2)

	# D, [2006-03-31T19:35:01.043938 #18088] DEBUG -- : Numerator: 10, denominator 2

	# => 5



	divide(10, 0)

	# D, [2006-03-31T19:35:01.045230 #18088] DEBUG -- : Numerator: 10, denominator 0

	# E, [2006-03-31T19:35:01.045495 #18088] ERROR -- : Error in division!: divided by 0

	# => nil
To change the log level, simply assign the appropriate constant to level:
	$LOG.level = Logger::ERROR
Now our logger will ignore all log messages except those with severity ERROR or FATAL:
	divide(10, 2)

	# => 5



	divide(10, 0)

	# E, [2006-03-31T19:35:01.047861 #18088] ERROR -- : Error in division!: divided by 0

	# => nil
Ruby's standard logging system works like Java's oft-imitated Log4J. The Logger object centralizes all the decisions about whether a particular message is important enough to be written to the log. When you write code, you simply assume that all the messages will be logged. At runtime, you can get a more or a less verbose log by changing the log level. A production application usually has a log level of
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Creating and Understanding Tracebacks
Inhaltsvorschau
You are debugging a program, and need to understand the stack traces that come with Ruby exceptions. Or you need to see which path the Ruby interpreter took to get to a certain line of code.
You can call the Kernel#caller method at any time to look at the Ruby interpreter's current call stack. The call stack is represented as a list of strings.
This Ruby program simulates a company with a top-down management style: one method delegates to another, which calls yet another. The method at the bottom can use caller to look upwards and see the methods that called it:
	 1  #!/usr/bin/ruby -w

	 2  # delegation.rb

	 3  class CEO

	 4    def CEO.new_vision

	 5      Manager.implement_vision

	 6    end

	 7   end

	 8

	 9   class Manager

	10     def Manager.implement_vision

	11       Engineer.do_work

	12     end

	13   end

	14

	15   class Engineer

	16     def Engineer.do_work

	17       puts 'How did I get here?'

	18       first = true

	19       caller.each do |c|

	20         puts %{#{(first ? 'I' : ' which')} was called by "#{c}"}

	21         first = false

	22       end

	23     end

	24   end

	25

	26   CEO.new_vision
Running this program illustrates the path the interpreter takes to Engineer.do_work:
	$ ./delegation.rb

	How did I get here?

	I was called by "delegation.rb:11:in 'implement_vision'"

	 which was called by "delegation.rb:5:in 'new_vision'"

	 which was called by "delegation.rb:26"
Each string in a traceback shows which line of Ruby code made some method call. The first bit of the traceback given above shows that Engineer.do_work was called by Manager.implement_vision on line 11 of the program. The second line shows how Manager.implement_vision was called, and so on.
Remember the stack trace displayed when a Ruby script raises an exception? It's the same one you can get any time by calling Kernel#caller. In fact, if you rescue an exception and assign it to a variable, you can get its traceback as an array of strings— the equivalent of calling caller on the line that triggered the exception:
	def raise_exception

	  raise Exception, 'You wanted me to raise an exception, so…'

	end



	begin

	  raise_exception

	rescue Exception => e

	  puts "Backtrace of the exception:\n #{e.backtrace.join("\n ")}"

	end

	# Backtrace of the exception:

	# (irb):2:in 'raise_exception'

	# (irb):5:in 'irb_binding'

	# /usr/lib/ruby/1.8/irb/workspace.rb:52:in 'irb_binding'

	# :0
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Writing Unit Tests
Inhaltsvorschau
Credit: Steve Arneil
You want to write some unit tests for your software, to guarantee its correctness now and in the future.
Use Test::Unit, the Ruby unit testing framework, from the Ruby standard library.
Consider a simple class for storing the name of a person. The Person class shown below stores a first name, a last name, and an age: a person's full name is available as a computed value. This code might go into a Ruby script called app/person.rb:
	# app/person.rb

	class Person

	  attr_accessor :first_name, :last_name, :age



	  def initialize(first_name, last_name, age)

	    raise ArgumentError, "Invalid age: #{age}" unless age > 0

	    @first_name, @last_name, @age = first_name, last_name, age

	  end



	  def full_name

	    first_name + ' ' + last_name

	  end

	end
Now, let's write some unit tests for this class. By convention, these would go into the file test/person_test.rb.
First, require the Person class itself and the Test::Unit framework:
	# test/person_test.rb

	require File.join(File.dirname(__FILE__), '..', 'app', 'person')

	require 'test/unit'
Next, extend the framework class Test::Unit::TestCase with a class to contain the actual tests. Each test should be written as a method of the test class, and each test method should begin with the prefix test. Each test should make one or more assertions: statements about the code which must be true for the code to be correct. Below are three test methods, each making one assertion:
	class PersonTest < Test::Unit::TestCase

	  def test_first_name

	    person = Person.new('Nathaniel', 'Talbott', 25)

	    assert_equal 'Nathaniel', person.first_name

	  end



	  def test_last_name

	    person = Person.new('Nathaniel', 'Talbott', 25)

	    assert_equal 'Talbott', person.last_name

	  end



	  def test_full_name

	    person = Person.new('Nathaniel', 'Talbott', 25)

	    assert_equal 'Nathaniel Talbott', person.full_name

	  end



	  def test_age person =

	    Person.new('Nathaniel', 'Talbott', 25)

	    assert_equal 25, person.age

	    assert_raise(ArgumentError) { Person.new('Nathaniel', 'Talbott', -4) }

	    assert_raise(ArgumentError) { Person.new('Nathaniel', 'Talbott', 'four') }

	  end

	end
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Running Unit Tests
Inhaltsvorschau
Credit: Steve Arneil
You want to run some or all of the unit tests you've written.
This solution uses the example test class PersonTest from the previous recipe, Recipe 17.7. In that scenario, this code lives in a file test/person_test.rb, and the code to be tested lives in app/person.rb. Here's test/person_test.rb again:
	# person_test.rb

	require File.join(File.dirname(__FILE__), '..', 'app', 'person')

	require 'test/unit'



	class PersonTest < Test::Unit::TestCase

	  FIRST_NAME, LAST_NAME, AGE = 'Nathaniel', 'Talbott', 25



	  def setup

	    @person = Person.new(FIRST_NAME, LAST_NAME, AGE)

	  end



	  def test_first_name

	    assert_equal FIRST_NAME, @person.first_name

	  end



	  def test_last_name

	    assert_equal LAST_NAME, @person.last_name

	  end



	  def test_full_name

	    assert_equal FIRST_NAME + ' ' + LAST_NAME, @person.full_name

	  end

	  def test_age

	    assert_equal 25, @person.age

	    assert_raise(ArgumentError) { Person.new(FIRST_NAME, LAST_NAME, -4) }

	    assert_raise(ArgumentError) { Person.new(FIRST_NAME, LAST_NAME, 'four') }

	  end

	end
As seen in the previous recipe, the simplest solution is to run the script that contains the tests as a Ruby script:
	$ ruby test/person_test.rb

	Loaded suite test/person_test

	Started

	….

	Finished in 0.008955 seconds.



	4 tests, 6 assertions, 0 failures, 0 errors
But the person_test.rb script also accepts command-line arguments. You can use the --name option to choose which test methods to run, and the --verbose option to print each test method as it's run:
	$ ruby test/person_test.rb --verbose --name test_first_name \

	  --name test_last_name

	Loaded suite test/person_test

	Started

	test_first_name(PersonTest): .

	test_last_name(PersonTest): .



	Finished in 0.012567 seconds.



	2 tests, 2 assertions, 0 failures, 0 errors
How do the tests run when person_test.rb doesn't appear to do anything but define a class? How can person_test.rb accept command-line arguments? We wrote that file, and we didn't put in any command-line parsing code.
It all happens behind the scenes. When we required the Test::Unit
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Testing Code That Uses External Resources
Inhaltsvorschau
Credit: John-Mason Shackelford
You want to test code without triggering its real-world side effects. For instance, you want to test a piece of code that makes an expensive network connection, or irreversibly modifies a file.
Sometimes you can set up an alternate data source to use for testing (Rails does this for the application database), but doing that makes your tests slower and imposes a setup burden on other developers. Instead, you can use Jim Weirich's FlexMock library, available as the flexmock gem.
Here's some code that performs a destructive operation on a live data source:
	class VersionControlMaintenance



	  DAY_SECONDS = 60 * 60 * 24



	  def initialize(vcs)

	    @vcs = vcs

	  end



	  def purge_old_labels(age_in_days)

	    @vcs.connect

	    old_labels = @vcs.label_list.select do |label|

	      label['date'] <= Time.now - age_in_days * DAY_SECONDS

	    end

	    @vcs.label_delete(*old_labels.collect{|label| label['name']})

	    @vcs.disconnect

	  end

	end
This code would be difficult to test by conventional means, with the vcs variable pointing to a live version control repository. But with FlexMock, it's simple to define a mock vcs object that can impersonate a real one.
Here's a unit test for VersionControlMaintenance#purge_old_labels that uses Flex-Mock, instead of modifying a real version control repository. First, we set up some dummy labels:
	require 'rubygems'

	require ' 

flexmock'

	require 'test/unit'



	class VersionControlMaintenanceTest < Test::Unit::TestCase



	  DAY_SECONDS = 60 * 60 * 24

	  LONG_AGO = Time.now - DAY_SECONDS * 3

	  RECENT = Time.now - DAY_SECONDS * 1

	  LABEL_LIST = [

	                { 'name' => 'L1', 'date' => LONG_AGO },

	                { 'name' => 'L2', 'date' => RECENT }

	               ]
We use FlexMock to define an object that expects a certain series of method calls:
	def test_purge

	  FlexMock.use("vcs") do |vcs|

	    vcs.should_receive(:connect).with_no_args.once.ordered

	    vcs.should_receive(:label_list).with_no_args.

	          and_return(LABEL_LIST).once.ordered



	    vcs.should_receive(:label_delete).

	          with('L1').once.ordered



	    vcs.should_receive(:disconnect).with_no_args.once.ordered
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Using breakpoint to Inspect and Change the State of Your Application
Inhaltsvorschau
You're debugging an application, and would like to be able to stop the program at any point and inspect the application's state (variables, data structures, etc.). You'd also like to be able to modify the application's state before restarting it.
Use the breakpoint library, available as the ruby-breakpoint gem.
Once you require ' breakpoint', you can call the breakpoint method from anywhere in your application. When the execution hits the breakpoint call, the application turns into an interactive Ruby session.
Here's a short Ruby program:
	#!/usr/bin/ruby -w

	# breakpoint_test.rb

	require 'rubygems'

	require 'breakpoint'



	class Foo

	  def initialize(init_value)

	    @instance_var = init_value

	  end



	  def bar

	    test_var = @instance_var

	    puts 'About to hit the breakpoint!'

	    breakpoint

	    puts 'HERE ARE SOME VARIABLES:'

	    puts "test_var: #{test_var}, @instance_var: #{@instance_var}"

	  end

	end



	f = Foo.new('When in the course')

	f.bar
When you run the application, you quickly hit the call to breakpoint in Foo#bar. This drops you into an irb session:
	$ ruby breakpoint_test.rb

	About to hit the breakpoint!

	Executing break point at breakpoint_test.rb:14 in 'bar'

	irb(#<Foo:0xb7452464>):001:0>
Once you quit the irb session, the program continues on its way:
	irb(#<Foo:0xb7452a18>):001:0>quit

	HERE ARE SOME VARIABLES:

	test_var: When in the course, @instance_var: When in the course
But there's a lot you can do within that irb session before you quit. You can look at the array local_variables, which enumerates all variables local to the current method. You can also look at and modify any of the variables that are currently in scope, including instance variables, class variables, and globals:
	$ ruby breakpoint_test.rb

	About to hit the breakpoint!

	Executing break point at breakpoint_test.rb:14 in 'bar'

	irb(#<Foo:0xb7452464>):001:0>local_variables

	=> ["test_var", "_"]

	irb(#<Foo:0xb7452428>):002:0> test_var

	=> "When in the course"

	irb(#<Foo:0xb7452428>):003:0> @instance_var

	=> "When in the course"

	irb(#<Foo:0xb7452428>):004:0> 
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Documenting Your Application
Inhaltsvorschau
You want to create a set of API documentation for your application. You might want to go so far as to keep all your documentation in the same files as your source code.
It's good programming practice to preface each of your methods, classes, and modules with a comment that lets the reader know what's going on. Ruby rewards this behavior by making it easy to transform those comments into a set of HTML pages that document your code. This is similar to Java's JavaDoc, Python's PyDoc, and Perl's Pod.
Here's a simple example. Suppose your application contains only one file, sum.rb, which defines only one method:
	def sum(*terms)

	  terms.inject(0) { |sum, term| sum + term}

	end
To document this application, use Ruby comments to document the method, and also to document the file as a whole:
	# Just a simple file that defines a sum method.



	# Takes any number of numeric terms and returns the sum.

	#   sum(1, 2, 3)                             # => 6

	#   sum(1, -1, 10)                           # => 10

	#   sum(1.5, 0.2, 0.3, 1)                    # => 3.0

	def sum(*terms)

	  terms.inject(0) { |sum, term| sum + term}

	end
Change into the directory containing the sum.rb file, and run the rdoc command.
	$ rdoc

	sum.rb: .

	Generating HTML…



	Files: 1

	Classes: 0

	Modules: 0

	Methods: 1

	Elapsed: 0.101s
The rdoc command creates a doc/ subdirectory beneath the current directory. It parses every Ruby file it can find in or below the current directory, and generates HTML files from the Ruby code and the comments that document it.
The index.html file in the doc/ subdirectory is a frameset that lets users navigate the files of your application. Since the example only uses one file (sum.rb), the most interesting thing about its generated documentation is what RDoc has done with the comments (Figure 17-1).
RDoc parses a set of Ruby files, cross-references them, and generates a web site that captures the class and module structure, and the comments you wrote while you were coding.
Generated RDoc makes for a useful reference to your classes and methods, but it's not a substitute for handwritten examples or tutorials. Of course, RDoc comments can
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Profiling Your Application
Inhaltsvorschau
You want to find the slowest parts of your application, and speed them up.
Include the Ruby profiler in your application with include 'profile' and the profiler will start tracking and timing every subsequent method call. When the application exits, the profiler will print a report to your program's standard error stream.
Here's a program that contains a performance flaw:
	#!/usr/bin/env ruby

	# sequence_counter.rb

	require 'profile'



	total = 0

	# Count the letter sequences containing an a, b, or c.

	('a'..'zz').each do |seq|

	  ['a', 'b', 'c'].each do |i|

	    if seq.index(i)

	      total += 1

	      break

	    end

	  end

	end

	puts "Total: #{total}"
When the program is run, the profiler shows the parts of the program that are most important to optimize:
	$ ruby sequence_counter.rb

	Total: 150

	  %    cumulative   self               self      total

	 time    seconds   seconds    calls   ms/call   ms/call  name

	 54.55      0.30      0.30      702      0.43      0.50  Array#each

	 32.73      0.48      0.18        1    180.00    550.00  Range#each

	  7.27      0.52      0.04     1952      0.02      0.02  String#index

	  3.64      0.54      0.02      702      0.03      0.03  String#succ

	  1.82      0.55      0.01      150      0.07      0.07  Fixnum#+

	…
The program takes about 0.3 seconds to run, and most of that is spent in Array#each. What if we replaced that code with an equivalent regular expression?
	#!/usr/bin/env ruby

	# sequence_counter2.rb

	require 'profile'



	total = 0

	# Count the letter sequences containing an a, b, or c.

	('a'..'zz').each {|seq| total +=1 if seq =~ /[abc]/ }

	puts "Total: #{total}"
Running this program yields a much better result:
	$ ruby sequence_counter2.rb

	Total: 150

	  %    cumulative       self               self      total

	 time    seconds       seconds   calls    ms/call   ms/call   name

	 83.33      0.05          0.05       1      50.00     60.00   Range#each

	 16.67      0.06          0.01     150       0.07      0.07   Fixnum#+

	  0.00      0.06          0.00       1       0.00      0.00   Fixnum#to_s

	…
The new version takes only 0.05 seconds to run, and as near as the profiler can measure, it's running nearly as fast as an empty iterator over the range
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Benchmarking Competing Solutions
Inhaltsvorschau
You want to see which of two solutions to a problem is faster. You might want to compare two different algorithms, or two libraries that do the same thing.
Use the benchmark library to time the tasks you want to run. The Benchmark.bm method gives you an object that can report on how long it takes for code blocks to run.
Let's explore whether the member? method is faster on arrays or hashes. First, we create a large array and a large hash with the same data, and define a method that exercises the member? method:
	RANGE = (0..1000)

	array = RANGE.to_a

	hash = RANGE.inject({}) { |h,i| h[i] = true; h }



	def test_member?(data)

	  RANGE.each { |i| data.member? i }

	end
Next, we call Benchmark.bm to set up a series of timing tests. The first test calls test_member? on the array; the second one calls it on the hash. The results are printed in a tabular form to standard error:
	require 'benchmark'



	Benchmark.bm(5) do |timer|

	  timer.report('Array') { test_member?(array) }

	  timer.report('Hash') { test_member?(hash) }

	end

	#        user      system       total        real

	# Array  0.260000    0.060000    0.320000 (  0.332583)

	# Hash   0.010000    0.000000    0.010000 (  0.001242)
As you'd expect, member? is much faster on a hash.
What do the different times mean? The real time is "wall clock" time: the number of seconds that passed in the real world between the start of the test and its completion. This time is actually not very useful, because it includes time during which the CPU was running some other process. If your system is operating under a heavy load, the Ruby interpreter will get less of the CPU's attention and the real times won't reflect the actual performance of your benchmarks. You only need real times when you're measuring user-visible performance on a running system.
The user time is time actually spent running the Ruby interpreter, and the system time is time spent in system calls spawned by the interpreter. If your test does a lot of I/O, its system time will tend to be large; if it does a lot of processing, its user time will tend to be large. The most useful time is probably
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Running Multiple Analysis Tools at Once
Inhaltsvorschau
You want to combine two analysis tools, like the Ruby profiler and the Ruby tracer. But when one tool calls set_trace_func, it overwrites the trace function left by the other.
Change set_trace_func so that it keeps an array of trace functions instead of just one. Here's a library called multitrace.rb that makes it possible:
	# multitrace.rb

	$TRACE_FUNCS = []



	alias :set_single_trace_func :set_trace_func

	def set_trace_func(proc)

	  if (proc == nil)

	    $TRACE_FUNCS.clear

	  else

	    $TRACE_FUNCS << proc

	  end

	end



	trace_all = Proc.new do |event, file, line, symbol, binding, klass|

	  $TRACE_FUNCS.each { |p| p.call(event, file, line, symbol, binding, klass)}

	end

	set_single_trace_func trace_all



	def unset_trace_func(proc)

	  $TRACE_FUNCS.delete(proc)

	end
Now you can run any number of analysis tools simultaneously. However, when one of the tools stops, they will all stop:
	#!/usr/bin/ruby -w

	# paranoia.rb

	require 'multitrace'

	require 'profile'

	require 'tracer'



	Tracer.on

	puts "I feel like I'm being watched."
This program's nervousness is well-justified, since its every move is being tracked by the Ruby tracer and timed by the Ruby profiler:
	$ ruby paranoia.rb

	#0:./multitrace.rb:9:Array:<:     $TRACE_FUNCS << proc

	#0:./multitrace.rb:11:Object:<: end

	#0:paranoia.rb:9::-: puts "I feel like I'm being watched."

	#0:paranoia.rb:9:Kernel:>: puts "I feel like I'm being watched."

	…

	  %       cumulative     self                  self       total

	 time       seconds     seconds     calls     ms/call    ms/call    name

	  0.00         0.00        0.00         1        0.00       0.00    Kernel.require

	  0.00         0.00        0.00         1        0.00       0.00    Fixnum#==

	  0.00         0.00        0.00         1        0.00       0.00    String#scan

	…
Without the include 'multitrace' at the beginning, only the profiler will run: its trace function will override the tracer's.
This example illustrates yet again how you can benefit by replacing some built-in part of Ruby. The multitrace library creates a drop-in replacement for set_trace_func
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Who's Calling That Method? A Call Graph Analyzer
Inhaltsvorschau
Suppose you're profiling a program such as the one in Recipe 17.12, and the profiler says that the top culprit is Array#each. That is, your program spends more time iterating over arrays than doing any one other thing:
	 %    cumulative    self               self      total

	time    seconds    seconds   calls    ms/call   ms/call  name

	12.19      2.74       2.74    4930       0.56      0.77  Array#each
This points you in the right direction, but where do you go from here? Most programs are full of calls to Array#each. To optimize your program, you need to know which lines of code are responsible for most of the Array#each calls. Ruby's profiler can't give tell you which line of code called a problem method, but it's easy to write a different profiler that can.
The heart of any Ruby profiler is a Proc object passed into the Kernel#set_trace_func method. This is a hook into the Ruby interpreter itself: if you set a trace function, it's called every time the Ruby interpreter does something interesting like call a method.
Here's the start of a CallTracker class. It initializes a hash-based data structure that tracks "interesting" classes and methods. It assumes that we pass a method tally_calls into set_trace_func; we'll define tally_calls a little later.
	class 

CallTracker



	  # Initialize and start the trace.

	  def initialize(show_stack_depth=1)

	    @show_stack_depth = show_stack_depth

	    @to_trace = Hash.new { |h,k| h[k] = {} }

	    start

	    at_exit { stop }

	end



	# Register a class/method combination as being interesting. Subsequent calls

	# to the method will be tallied by tally_calls.

	def register(klass, method_symbol)

	  @to_trace[klass][method_symbol] = {}

	end



	# Tells the Ruby interpreter to call tally_calls whenever it's about to

	# do anything interesting.

	def start

	  set_trace_func method(:tally_calls).to_proc

	end



	# Stops the profiler, and prints a report of the interesting calls made

	# while it was running.

	def stop(out=$stderr)

	  set_trace_func nil

	  report(out)

	end
Now let's define the missing methods
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Chapter 18: Packaging and Distributing Software
Inhaltsvorschau
No matter how productive it makes you, a programming language won't save you any time if you can't take advantage of a body of code written by other people. A community works faster than any one person, and it's usually easier to install and learn a library than to write and debug the same code yourself.
That is, if you can find the library in the first place. And if you're not sucked into an mess of dependencies that grow and grow, making you want to write the code yourself just so you can be doing some real programming.
The success of Perl's CPAN archive has made the Ruby community work on our own centralized code repository and packaging system. Whatever you think of Perl, you must admit that a Perl programmer can find just about any library they need in CPAN. If you write your own Perl library, you know where to send it: CPAN. This is not really a technical aspect of Perl, but it's a powerful component of that language's popularity.
The problem of packaging is more a logistical problem than a technical one. It's a matter of coordination: getting everyone to agree on a single mechanism for installing packages, and a single place to go to find those packages. For Ruby, the installation mechanism is Ruby gems (or rubygems or just "gems"), and rubyforge.org is the place to go to find gems (packaged libraries and programs).
In many recipes in this book, we tell you to use a gem for some task: the alternative is often to show you pages and pages of code. This chapter covers how to find the gems you need, install them, and package your own software as gems so that others can benefit from your work.
You may need to find and install the Ruby gems system itself. It comes installed by default on Windows, but not on Unix. You can download it from this URL:
	http://rubyforge.org/frs/?group_id=126
To install the Ruby gems package, unzip the tarball or ZIP file, and run the setup.rb script within. You can then use the gem command to search for and install gems, as described in Recipes 18.1 and 18.2. You can also build your own gems from "gemspec" files, as described in Recipe 18.6, and upload it to RubyForge or some other site (Recipe 18.7).
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Finding Libraries by Querying Gem Respositories
Inhaltsvorschau
You want to find new gems to install on your system, or see which gems you already have installed.
From the command line, use gem's query command:
	$ gem query

	*** LOCAL GEMS ***



	sources (0.0.1)

	   This package provides download sources for remote gem installation



	$ gem query --remote

	*** REMOTE GEMS ***

	actionmailer (1.1.1, 1.0.1, 1.0.0, 0.9.1, 0.9.0, 0.8.1, …)

	     Service layer for easy email delivery and testing.



	actionpack (1.10.1, 1.9.1, 1.9.0, 1.8.1, 1.8.0, 1.7.0, …)

	    Web-flow and rendering framework putting the VC in MVC.



	[… Much more output omitted ….]
From Ruby code, use Gem::cache to query your locally installed gems, and Gem::RemoteInstaller#search to query the gems on some other site. Gem::cache can be treated as an Enumerable full of tasty Gem::Specification objects. Gem::Remote-Installer#search returns an Array containing an Array of Gem::Specification objects for every remote source it searched. Usually there will only be one remote source—the main gem repository on rubyforge.org.
This Ruby code iterates over the locally installed gems:
	require 'rubygems'



	Gem::cache.each do |name, gem|

	  puts %{"#{gem.name}" gem version #{gem.version} is installed.}

	end

	# "sources" gem version 0.0.1 is installed
The format_gems method defined below gives a convenient way of looking at a large set of Gem::Specification objects. It groups the gems by name and version, then prints a formatted list:
	require 'rubygems/remote_installer'

	require 'yaml'



	def 

format_gems(gems)

	  gem_versions = gems.inject({}) { |h, gem| (h[gem.name] ||= []) << gem; h}

	  gem_versions.keys.sort.each do |name|

	   versions = gem_versions[name].collect { |gem| gem.version.to_s }

	    puts "#{name} is available in these versions: #{versions.join(', ')}"

	  end

	end
Here it is being run on the gems available from RubyForge:
	format_gems(Gem::RemoteInstaller.new.search(/.*/).flatten)

	# Asami is available in these versions: 0.04

	# Bangkok is available in these versions: 0.1.0

	# Bloglines4R is available in these versions: 0.1.0

	# BlueCloth is available in these versions: 0.0.2, 0.0.3, 0.0.4, 1.0.0

	# …
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Installing and Using a Gem
Inhaltsvorschau
You want to install a gem, then use the code it provides in your programs.
You can install the latest version of a gem with the gem install command. This command looks for an uninstalled gem file on your local system; if it can't find one, it calls out to an external source (gems.rubyforge.org, unless you specify otherwise) asking for a gem file. Since gem install changes the system-wide Ruby installation, you'll need to have superuser access to run it.
	$ gem install RedCloth

	Attempting local installation of 'RedCloth'

	Local gem file not found: RedCloth*.gem

	Attempting remote installation of 'RedCloth'

	Successfully installed RedCloth-3.0.4
A gem contains standard Ruby code files, and once you install the gem, you can require those files normally and use the classes and modules they define. However, gems are not installed in the same path as the standard Ruby libraries, so you'll need to tell Ruby to supplement its normal library path with the path to the gems. The simplest way is to require 'rubygems' in any program that uses a gem, before you write any require statements for libraries installed via gems. This is the solution we use throughout this book.
	# This code assumes the "redcloth" gem has been installed, as in the

	# code above.

	require 'redcloth'

	# LoadError: no such file to load -- redcloth



	require ' 

rubygems'

	require 'redcloth'

	parser = RedCloth::CommandParser.new

	# …
For a solution that works across Ruby scripts, you'll need to change your Ruby runtime environment, either by setting the RUBYOPT environment variable to rubygems, or by aliasing your ruby command so that it always passes in a -rubygems option to the interpreter.
	$ ruby -e "require 'redcloth'; puts 'Success'"

	-e:1:in `require': no such file to load -- redcloth (LoadError)

	        from -e:1



	$ ruby -rubygems -e "require 'redcloth'; puts 'Success'"

	Success



	# On Unix:

	$ export RUBYOPT=rubygems

	$ ruby -e "require 'redcloth'; puts 'Success'"

	Success



	# On Windows:

	$ set RUBYOPT=rubygems

	$ ruby -e "require 'redcloth'; puts 'Success'"

	Success
Once you've installed a gem, you can upgrade it to the latest version with the
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Requiring a Specific Version of a Gem
Inhaltsvorschau
Your program depends on an interface or feature of a gem found only in particular versions of the library. If a user tries to run your program with the wrong version installed, you want to tell them which version you require, so they can upgrade.
The rubygems library defines a method, Kernel#require_gem, which is a kind of assertion method for gems. It will raise a Gem::LoadError if the given gem is not installed, or if no installed version of a gem meets your requirements.
The easiest solution is to allow any version of a gem; you don't need to use require_gem at all:
	require 'rubygems'

	require 'cmdparse'                               # => true
This is equivalent to requiring a minimum version of 0.0.0:
	require_gem 'nosuchgem'

	# Gem::LoadError: Could not find RubyGem nosuchgem (> 0.0.0)
If you can't use just any version of a gem, it's usually safe to require a minimum version, relying on future versions to be backwards-compatible:
	require_gem 'cmdparse', '>= 1.0' #                          => false

	require_gem 'cmdparse', '>= 2.0.3'

	# Gem::LoadError: RubyGem version error: cmdparse(2.0.0 not >= 2.0.3)
Although you may already be familiar with it, a brief review of the structure of version numbers is useful here. A version number for a Ruby gem (and most other pieces of open source software) has three parts: a major version number, a minor version number, and a revision number or build number (Figure 18-1).
Figure 18-1: Anatomy of a version number
Some packages have only a major and minor version number (such as 2.0 or 1.6), and some have additional numbers after the revision number, but the three-number convention is the accepted standard for numbering Ruby gems.
The revision number is incremented at every new public release of the software. If the revision contains more than minor changes, or changes the public API in a backwards-compatible way, the author increments the minor version and resets the revision number to zero. When a release contains large changes, especially ones that change the public API in backwards-incompatible ways, the author usually increments the major version number, and resets the minor version and revision number to zero.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Uninstalling a Gem
Inhaltsvorschau
You want to remove an installed gem from your Ruby installation.
From the command line, use the gem uninstall command:
	$ gem uninstall blinkenlights

	Attempting to uninstall gem 'blinkenlights'

	Successfully uninstalled blinkenlights version 0.0.2
From Ruby code, the most reliable way to uninstall a gem is to simulate a command-line invocation with the Gem::GemRunner class. This code installs a gem, then immediately removes it:
	require 'rubygems'

	require 'rubygems/installer'

	require 'rubygems/remote_installer'

	Gem::RemoteInstaller.new.install('blinkenlights')



	require 'rubygems/gem_runner'

	require 'rubygems/doc_manager'

	Gem.manage_gems

	Gem::GemRunner.new.run(['uninstall', 'blinkenlights'])

	# Successfully uninstalled blinkenlights version 0.0.4
Uninstalling a gem can disrupt the normal workings of your Ruby programs, so I recommend you only uninstall gems from the command line. That way, there's less chance of a bug wiping out all your gems.
Since rubygems can manage multiple installed versions of the same gem, you won't usually have to remove old copies of gems. There are three main reasons to remove gems:
  1. You find out that a particular version of a gem is buggy, and you want to make sure it never gets used.
  2. You want to save disk space.
  3. You want to clean up the list of installed gems so that it's more obvious which gems you actually use.
If uninstalling a gem would leave another installed gem with an unmet dependency, you'll be told about the dependency and asked whether you want to go through with the uninstall anyway. You'll get this interactive prompt whether you run the gem uninstall command or whether you use the Gem::Uninstaller class from Ruby code.
	Gem::Uninstaller.new('actionpack', {}).uninstall

	# You have requested to uninstall the gem:

	#        actionpack-1.8.1

	# actionmailer-0.9.1 depends on [actionpack (= 1.8.1)]

	# If you remove this gem, the dependency will not be met.

	# Uninstall anyway? [yN]
The sources gem is a special gem that tells rubygems to look for remotely installable gems at http://gems.rubyforge.org/ by default. If you uninstall this gem, you won't be able to install any more gems, except through complicated hacks of the classes in the
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Reading Documentation for Installed Gems
Inhaltsvorschau
You want to read the RDoc documentation for the gems you have installed. Although some gem projects provide human-written documentation like tutorials, the generated RDoc documentation isn't usually available online.
RDoc documentation isn't usually available online because when you install a gem, Ruby generates your very own HTML copy of the RDoc documentation and installs it along with the software. The documentation you need is probably already on your computer.
The simplest way to browse the documentation for your installed gems is to run the gem_server command, then visit http://localhost:8808/. You'll see all your installed gems in a table form, and be able to browse the generated documentation of each gem that provides any.
Otherwise, you can find your Rubygems documentation directory, and browse the installed documentation with local filesystem tools.
The generated rdoc for a gem is kept in the doc/ subdirectory of the base directory in which the gem was installed. For instance, on my computer, gems are installed in /usr/lib/ruby/gems/1.8/. For every gem that has RDoc, the generated HTML documentation will be kept in the directory /usr/lib/ruby/gems/1.8/doc/[gem name]/rdoc/. If I were to install one particular gem to another directory, the documentation for the gem would be in a doc/ subdirectory of that directory.
Here's some code that prints out the location of the RDoc files for every installed gem. Unless you've installed specific gems in nonstandard locations, they'll all be in the doc/ subdirectory of Gem.dir. This code snippet also shows off some of the capabilities of Gem::DocManager, the Ruby class you can use to manipulate a gem's RDoc.
	require 'rubygems'

	Gem.manage_gems



	def show_gem_rdoc

	  puts "Your generated docs are all probably in #{File.join(Gem.dir, "doc")}"



	  puts "Just to be safe, I'll print out every gem's RDoc location:"

	  specifications_dir = File.join(Gem.dir, 'specifications')

	  lacking_rdoc = []

	  Gem::SourceIndex.from_installed_gems(specifications_dir).each do |path, spec|

	    manager = Gem::DocManager.new(spec)

	    if manager.rdoc_installed?

	      doc_path = File.join(spec.installation_path, 'doc', spec.full_name)

	      puts " #{spec.full_name} => #{doc_path}"

	    else

	      lacking_rdoc << spec.full_name

	    end

	  end



	  unless lacking_rdoc.empty?

	    puts "\nThese installed gems have no RDoc installed:"

	    puts " #{lacking_rdoc.join("\n ")}"

	  end

	end



	show_gem_rdoc

	# Your generated RDoc is probably all in /usr/lib/ruby/gems/1.8/doc

	# Just to be safe, I'll print out every gem's RDoc location:

	#  flexmock-0.1.7 => /usr/lib/ruby/gems/1.8/doc/flexmock-0.1.7

	#  simple-rss-1.1 => /usr/lib/ruby/gems/1.8/doc/simple-rss-1.1

	#  classifier-1.3.0 => /usr/lib/ruby/gems/1.8/doc/classifier-1.3.0

	#  actionmailer-1.1.5 => /usr/lib/ruby/gems/1.8/doc/actionmailer-1.1.5

	# …

	#

	# These installed gems have no RDoc installed:

	#  Ruby-MemCache-0.0.1

	#  RedCloth-3.0.4

	#  sources-0.0.1

	# …
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Packaging Your Code as a Gem
Inhaltsvorschau
You want to package a program you wrote as a Ruby gem, possibly to distribute it on the main gem server at rubyforge.org.
First, you must write a specification file. This file consists of a few lines of Ruby code that instantiate a Gem::Specification object and populate it with information about your program. Assuming that all of your program's files are in a subdirectory called lib/, the following might make a good specification file:
	# shielding.gemspec

	require 'rubygems'

	spec = Gem::Specification.new do |spec|

	  spec.name = 'shielding'

	  spec.summary = 'A library for calculating the strength of duophasic shielding'

	  spec.description = %{This library calculates to high precision the

	  physical and electrostatic strength of a duophasic shield. It knows

	  about most real-world shield configurations, as well as many

	  theoretical arrangements not yet built.}

	  spec.author = 'Bob Zaff'

	  spec.email = 'zaff@example.com'

	  spec.homepage = 'http://www.example.com/software/shielding/'

	  spec.files = Dir['lib/*.rb']

	  spec.version = '1.0.0'

	end
You can then use the gem build command to create the actual gem from its specification file:
	$ gem build shielding.gemspec

	Attempting to build gem spec 'shielding.gemspec'

	  Successfully built RubyGem

	  Name: shielding

	  Version: 1.0.0

	  File: shielding-1.0.0.gem



	$ ls

	shield.gemspec shielding-1.0.0.gem
Then install the gem normally:
	$ gem install ./shielding-1.0.0.gem

	Attempting local installation of './shielding-1.0.0.gem'

	Successfully installed shielding, version 1.0.0

	Installing RDoc documentation for shielding-1.0.0…

	WARNING: Generating RDoc on .gem that may not have RDoc.
You can also build a gem from within Ruby code by passing the completed Gem::Specification into a Gem::Builder object.
	require 'rubygems/builder'

	builder = Gem::Builder.new(spec).build

	# Successfully built RubyGem

	# Name: shielding

	# Version: 1.0.0

	# File: shielding-1.0.0.gem

	# => "shielding-1.0.0.gem"
Gem::Builder is useful as a starting point for automating your releases, but if you're interested in doing that, you should use Rake (see Chapter 19, especially Recipe 19.4).
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Distributing Your Gems
Inhaltsvorschau
You've packaged your software as a Ruby gem, but nobody knows about it. You want to make your gem easy to find and install, so that your genius does not go unrecognized.
The simplest solution (for you, at least) is to upload your .gem file to a web site or FTP site. Your users can download the .gem file, then install it by passing the filename into the gem install command:
	$ wget http://www.example.com/gems/my_gem-1.0.4.gem

	--10:40:10-- http://www.example.com/gems/my_gem-1.0.4.gem

	           => `my_gem-1.0.4.gem'

	Resolving gems.example.com… 204.127.202.4

	Connecting to gems.example.com|204.127.202.4|:80… connected.

	HTTP request sent, awaiting response… 200 OK

	Length: 40,823 (40K) [text/plain]



	100%[====================================>] 40,823        46.96K/s



	10:40:11 (46.85 KB/s) - `my_gem-1.0.4.gem' saved [40823/40823]



	$ gem install ./my_gem-1.0.4.gem

	Attempting local installation of './my_gem-1.0.4.gem'

	Successfully installed my_gem, version 1.0.4

	Installing RDoc documentation for my_gem-1.0.4…
If your gem has dependencies, the end user must separately install the dependencies before installing a downloaded gem, or the gem command will become confused and die. This will happen even if the user specifies the --include-dependencies flag:
	$ gem install --include-dependencies ./my_gem_with_dependency-1.0.0.gem

	Attempting local installation of './my_gem_with_dependency.1.0.0.gem'

	ERROR: Error installing gem ./my_gem_with_dependency-1.0.0.gem[.gem]:

	 my_gem_with_dependency requires my_dependency > 0.0.0
If you distribute your gem from a web site, be sure to set the homepage attribute in your gemspec file.
Gems are usually distributed through HTTP. A web server might serve standalone .gem files intended for download by the end user, or it might also serve some metadata that allows the gem command to download and install gems on its own.
There are several ways of setting up gems for distribution. In general you must negotiate a tradeoff between the developer's (your) convenience and the end user's ease of installation. The Rubygems package makes it easy to install and manage third-party Ruby packages, but the developers of those packages have to jump through some hoops if they want to make the installation process as transparent as possible.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Installing and Creating Standalone Packages with setup.rb
Inhaltsvorschau
You want to install a Ruby package that includes a setup.rb script instead of being packaged as a Ruby gem. Or, you want to make it possible for people to install your software package without having to install Ruby gems.
To install a setup-rb—based Ruby package as root or the administrative user, simply run the setup.rb script:
	$ ruby setup.rb
By default, setup.rb installs a package into your site_ruby directory. If you don't have root access or only want to install the package for your own use, you can install the package into your home directory, like this:
	$ ruby setup.rb all --installdirs=home
That command installs the package into the lib/ruby/ subdirectory of your home directory. Make sure you have that directory included in your RUBYLIB environment variable, or Ruby won't know to look there when you require a library. You can check your library path with the special $: global variable:
	$:

	# => ["/home/leonardr/lib/ruby", "/usr/local/lib/site_ruby/1.8", … ]

	require 'installed_via_setup'

	# => true
Because Ruby gems are not yet part of the standard Ruby library, some people prefer to package their software releases as self-contained archives. A package that includes a setup.rb installation script contains all the code and data necessary for installation; it might have dependencies, but it doesn't rely on another component just to get itself installed. The rubygems package itself is installed via setup.rb, since it can't assume that the system already supports gem-based installations.
You might also use a setup.rb script instead of a Ruby gem if you want to add Ruby hook scripts to the installation procedure. For instance, you might want to create a new database when your package is installed. Once the Rubygems package is included in the Ruby standard library, this will be just about the only reason left not to package all your software as Ruby gems. Even native C extensions can be included in a Ruby gem and built as part of the gem installation.
Ruby gems and setup.rb impose similar file structures on your package: your Ruby libraries go into a lib/ subdirectory, command-line applications go into a
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Chapter 19: Automating Tasks with Rake
Inhaltsvorschau
Even when your software is written, tested, and packaged, you're still not done. You've got to start working on the next version, and the next… Every release you do, in some cases every change you make to your code, will send you running through a maze of repetitive tasks that have nothing to do with programming.
Fortunately, there's a way to automate these tasks, and the best part is that you can do it by writing more Ruby code. The answer is Rake.
Rake is a build language, Ruby's answer to Unix make and Java's Ant. It lets you define tasks: named code bocks that carry out specific actions, like building a gem or running a set of unit tests. Invoke Rake, and your predefined tasks will happily do the work you once did: compiling C extensions, splicing files together, running unit tests, or packaging a new release of your software. If you can define it, Rake can run it.
Rake is available as the rake gem; if you've installed Rails, you already have it. Unlike most gems, it doesn't just install libraries: it installs a command-line program called rake, which contains the logic for actually performing Rake tasks. For ease of use, you may need to add to your PATH environment variable the directory containing the rake script: something like /usr/lib/ruby/gems/1.8/gems/rake-0.6.2/bin/. That way you can just run rake from the command line.
A Rakefile is just a Ruby source file that has access to some special methods: task, file, directory, and a few others. Calling one of these methods defines a task, which can be run by the command-line rake program, or called as a dependency by other tasks.
The most commonly used method is the generic one: task. This method takes the name of the task to define, and a code block that implements the task. Here's a simple Rakefile that defines two tasks, cross_bridge and build_bridge, one of which depends on the other. It designates cross_bridge as the default task by defining a third task called default which does nothing except depend on cross_bridge.
	# Rakefile

	desc "Cross the bridge."

	task :cross_bridge => [:build_bridge] do

	  puts "I'm crossing the bridge."

	end



	desc "Build the bridge"

	task :build_bridge do

	  puts 'Bridge construction is complete.'

	end



	task :default => [:cross_bridge]
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Automatically Running Unit Tests
Inhaltsvorschau
Credit: Pat Eyler
You want to make it easy to run your project's unit test suite. You also want the tests to run automatically before you do a new release of your project.
Require the rake/testtask library and create a new Rake::TestTask. Save the following code in a file called Rakefile in the project's top-level directory (or add it to your existing Rakefile).
	require ' 

rake/testtask'



	Rake::TestTask.new('test') do |t|

	  t.pattern = 'test/**/tc_*.rb'

	  t.warning = true

	end
This Rakefile makes two assumptions:
  1. The Test::Unit test cases live in files under the test directory (and its subdirectories). The names of these files start with tc_ and end in .rb.
  2. The Ruby libraries to be tested live under the lib directory. Rake automatically appends this directoy to Ruby's load path, the list of directories that Ruby searches when you try to require a library.
To execute your test cases, run the command rake test in the project's top-level directory. The tests are loaded by a new Ruby interpreter with warnings enabled. The output is the same as you'd see from Test::Unit's console runner.
If it's easy to trigger the test process, you'll run your tests more often, and you'll detect problems sooner. Rake makes it really convenient to run your tests.
We can make the test command even shorter by defining a default task. Just add the following line to the Rakefile. The position within the file doesn't matter, but to keep things clear, you should put it before other task definitions:
	task "default" => ["test"]
Now, whenever we run rake without an argument, it will invoke the test task. If your Rakefile already has a default task, you should be able to just add the test task to its list of prerequisites. Similarly, if you have a task that packages a new release of your software (like the one defined in Recipe 19.4), you can make the test task a prerequisite. If your tests fail, your package won't be built and you won't release a buggy piece of software.
The Rake::TestTask has a special attribute,
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Automatically Generating Documentation
Inhaltsvorschau
Credit: Stefan Lang
You want to automatically create HTML pages from the RDoc formatted comments in your code, and from other RDoc formatted files.
Within your Rakefile, require the rake/rdoctask library and create a new Rake:: RDocTask. Here's a typical example:
	require 'rake/rdoctask'



	Rake::RDocTask.new('rdoc') do |t|

	  t.rdoc_files.include('README', 'lib/**/*.rb')

	  t.main = 'README'

	  t.title = "MyLib API documentation"

	end
Now you can run the command rake rdoc from a shell in your project's top-level directory. This particular Rake task creates API documentation for all files under the lib directory (and its subdirectories) whose names end in .rb. Additionally, the RDoc-formatted contents of the top-level README file will appear on the front page of the documentation.
The HTML output files are written under your project's %(filename)html% directory. To read the documentation, point your browser to %(filename)html/index.html%. The browser will show "MyLib API documentation" (that is, the value of the task's title) as the page title.
It is common practice among authors of Ruby libraries to document a library's API with RDoc-formatted text. Since Ruby 1.8.1, a standard Ruby installation contains the rdoc tool, which extracts the RDoc comments from source code and creates nicely formatted HTML pages.
Unlike the tasks you define from scratch with the task method, but like the TestTask covered in Recipe 19.1, Rake::RDocTask.new takes a code block, which is executed immediately at task definition time. The code block lets you customize how your RDoc documentation should look. After running your code block, the Rake:: RDocTask object defines three new Rake tasks:
rdoc
Updates the HTML documentation by running RDoc.
clobber_rdoc
Removes the directory and its contents created by the rdoc task.
rerdoc
Force a rebuild of the HTML-documentation. Has the same effect as running clobber_rdoc followed by rdoc.
Now we know enough to integrate the
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Cleaning Up Generated Files
Inhaltsvorschau
Credit: Stefan Lang
You want to clean up files that aren't actually part of your project: generated files, backup files, and so on.
Within your Rakefile, require the rake/clean library to get access to the clean and clobber tasks. Put glob patterns for all your generated files in the CLOBBER FileList. Put glob patterns for all other scratch files in the CLEAN FileList.
By default, CLEAN also includes the patterns **/*~, **/*.bak, and **/core. Here's a typical set of CLOBBER and CLEAN files:
	require ' 

rake/clean'



	# Include the "pkg" and "doc" directories and their contents.

	# Include all files ending in ".o" in the current directory

	# and its subdirectories (recursively).

	CLOBBER.include('pkg', 'doc', '**/*.o')



	# Include InstalledFiles and .config: files created by setup.rb.

	# Include temporary files created during test run.

	CLEAN.include('InstalledFiles', '.config', 'test/**/*.tmp')
Run rake clean to remove all files specified by the CLEAN filelist, and rake clobber to remove the files specified by both file lists.
The rake/clean library initializes the constants CLEAN and CLOBBER to new Rake:: FileList instances. It also defines the tasks clean and clobber, making clean a prerequisite of clobber. The idea is that rake clean removes any files that might need to be recreated once your program changes, while rake clobber returns your source tree to a completely pristine state.
Other Rake libraries define cleanup tasks that remove certain products of their main tasks. An example: the packaging libraries create a task called clobber_package, and make it a prerequisite of clobber. Running rake clobber on such a project removes the package files: you don't have to explicitly include them in your CLOBBER list.
You can do the same thing for your own tasks: rather than manipulate CLEAN and CLOBBER, you can create a custom cleanup task and make it a prerequisite of clean or clobber. The following code is a different way of making sure that rake clobber removes any precompiled object files:
	desc 'Remove all object files.'

	task 'clobber_objects' do

	  rm_f FileList['**/*.o']

	end



	# Make clobber_objects a prerequisite of the preexisting clobber task

	task 'clobber' => 'clobber_objects'
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Automatically Building a Gem
Inhaltsvorschau
Credit: Stefan Lang
You want to automatically build a gem package for your application or library whenever you do a release.
Require the rake/gempackagetask library within your Rakefile, and create a Gem:: Specification instance that describes your project. Feed it to the Rake:: GemPackageTask constructor, which automatically defines a number of gem-related tasks:
	require 'rake/gempackagetask'



	# Create a gem specification

	gem_spec = Gem::Specification.new do |s|

	  s.name = 'docbook'

	  s.version = '1.0.0'

	  s.summary = 'DocBook formatting program and library.'



	  # Files containing Test::Unit test cases.

	  s.test_files = FileList['tests/**/*']



	  # Executable scripts under the "bin" directory.

	  s.executables = ['voc']



	  # List of other files to be included.

	  s.files = FileList['README', 'ChangeLog', 'lib/**/*.rb']

	end



	Rake::GemPackageTask.new(gem_spec) do |pkg|

	  pkg.need_zip = false

	  pkg.need_tar = false

	end
Run the command rake package, and (assuming those files actually exist), Rake will build a gem file docbook-1.0.0.gem under the pkg/ directory.
The RubyGems library provides the Gem::Specification class, and Rake provides the Rake::GemPackageTask class that uses it. Creating a new Rake::GemPackageTask object automatically defines the three tasks: package, clobber_package, and repackage.
The package task builds a gem inside the project's pkg/ directory. The clobber_package task removes the pkg/ directory and its contents. The repackage task just invokes clobber_package to remove any old package file, and then invokes package to rebuild them from scratch.
The example above sets to false the attributes need_zip and need_tar of the Rake::GemPackageTask. If you set them to true, then in addition to a gem you'll get a ZIP file and a gzipped tar archive containing the same files as the gem. Note that Rake uses the zip and tar command-line tools, so if your system doesn't provide them (the way a standard Windows installation doesn't), the package task won't be able to create these ZIP or tar archives.
The package
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Gathering Statistics About Your Code
Inhaltsvorschau
Credit: Stefan Lang
You want to gather statistics about your Ruby project, like the total number of lines of code.
Here's a class that parses Ruby source files and gathers statistics. Put this in scriptlines.rb in your project's top-level directory.
	# scriptlines.rb

	# A ScriptLines instance analyses a Ruby script and maintains

	# counters for the total number of lines, lines of 

code, etc.

	class ScriptLines



	  attr_reader :name

	  attr_accessor :bytes, :lines, :lines_of_code, :comment_lines



	  LINE_FORMAT = '%8s %8s %8s %8s %s'



	  def self.headline

	    sprintf LINE_FORMAT, "BYTES", "LINES", "LOC", "COMMENT", "FILE"

	  end



	  # The 'name' argument is usually a filename

	  def initialize(name)

	    @name = name

	    @bytes = 0

	    @lines = 0    # total number of lines

	    @lines_of_code = 0

	    @comment_lines = 0

	  end



	  # Iterates over all the lines in io (io might be a file or a

	  # string), analyses them and appropriately increases the counter

	  # attributes.

	  def read(io)

	    in_multiline_comment = false

	    io.each { |line|

	      @lines += 1

	      @bytes += line.size

	      case line

	      when /^=begin(\s|$)/

	        in_multiline_comment = true

	        @comment_lines += 1

	      when /^=end(\s|$)/:

	        @comment_lines += 1

	        in_multiline_comment = false

	      when /^\s*#/

	        @comment_lines += 1

	      when /^\s*$/

	        # empty/whitespace only line

	      else

	        if in_multiline_comment

	          @comment_lines += 1

	        else

	          @lines_of_code += 1

	        end

	      end

	    }

	  end



	  # Get a new ScriptLines instance whose counters hold the

	  # sum of self and other.

	  def +(other)

	    sum = self.dup

	    sum.bytes += other.bytes

	    sum.lines += other.lines

	    sum.lines_of_ 

code += other.lines_of_code

	    sum.comment_lines += other.comment_lines

	    sum

	  end



	  # Get a formatted string containing all counter numbers and the

	  # name of this instance.

	  def to_s

	    sprintf LINE_FORMAT,

	      @bytes, @lines, @lines_of_code, @comment_lines, @name

	  end

	end
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Publishing Your Documentation
Inhaltsvorschau
Credit: Stefan Lang
You want to automatically update your project's web site on RubyForge (or some other site) with generated documentation or custom pages.
As seen in Recipe 19.2, Rake provides a RDocTask for generating RDoc documentation:
	require 'rake/rdoctask'



	html_dir = 'doc/html'

	library = 'MyLib'

	Rake::RDocTask.new('rdoc') do |t|

	  t.rdoc_files.include('README', 'lib/**/*.rb')

	  t.main = 'README'

	  t.title = "#{library} API documentation"

	  t.rdoc_dir = html_dir

	end
To upload your generated documentation to RubyForge, use this task along with the upload-docs task defined below. The Unix scp command-line tool does the actual work of uploading:
	# Define your RubyForge username and your project's Unix name here:

	rubyforge_user = 'user'

	rubyforge_project = 'project'

	rubyforge_path = "/var/www/gforge-projects/#{rubyforge_project}/"

	desc 'Upload documentation to RubyForge.'

	task 'upload-docs' => ['rdoc'] do

	     sh "scp -r #{html_dir}/* " +

	         "#{rubyforge_user}@rubyforge.org:#{rubyforge_path}"

	end
Set off the publishing process by invoking rake upload-docs. The upload-docs task has the rdoc task as a prerequisite, so the HTML pages under doc/html/ will be created if necessary.
Then scp prompts for your RubyForge account password. Enter it, and all files under doc/html/ and its subdirectories will be uploaded to RubyForge. The docs will become available under http://project.rubyforge.org/, where "project" is the Unix name of your project. Now your users can read your RDoc online without having to generate it themselves. Your documentation will also show up in web search results.
Rake's sh method starts an instance of the OS's standard shell. This feature is used to run the scp command-line tool. This means that this recipe will only work if scp is installed on your system.
The scp command copies all the files that the RDoc placed under doc/html/, to the root of your project's web site on the RubyForge server. In effect, the main page of the API documentation will appear as your project's homepage. Some RubyForge projects don't have a custom homepage, so this is a good place to put the RDoc. If you want a custom homepage, just copy the RDoc into a different directory by changing
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Running Multiple Tasks in Parallel
Inhaltsvorschau
Your build process takes too long to run. Rake finishes copying one set of files only to start copying another set. You could save time by running these tasks in parallel, instead of stringing them one after another.
Define a task using the multitask function instead of task. Each of that task's prerequisites will be run in a separate thread.
In this code, I'll define two long-running tasks:
	task 'copy_docs' do

	  # Simulate a large disk copy.

	  sleep 5

	end



	task 'compile_extensions' do

	  # Simulate a C compiler compiling a bunch of files.

	  sleep 10

	end



	task 'build_serial' => ['copy_docs', 'compile_extensions']

	multitask 'build_parallel' => ['copy_docs', 'compile_extensions']
The build_serial task runs in about 15 seconds, but the build_parallel task does the same thing in about 10 seconds.
A multitask runs just like a normal task, except that each of its dependencies runs in a separate thread. When running the dependencies of a multitask, Rake first finds any common secondary dependencies of these dependencies, and runs them first. It then spawns a separate thread for each dependency, so that they can run simultaneously.
Consider three tasks, ice_cream, cheese, and yogurt, all of which have a dependency on buy_milk. You can run the first three tasks in separate threads with a multitask, but Rake will run buy_milk before creating the threads. Otherwise, ice_cream, cheese, and yogurt would all trigger buy_milk, wasting time.
When your tasks spend a lot of time blocking on I/O operations (as many Rake tasks do), using a multitask can speed up your builds. Unfortunately, it can also cause the same problems you'll see with any multithreaded code. If you've got a fancy Rakefile, in which the tasks keep state inside Ruby data structures, you'll need to synchronize access to those data structures to prevent multithreading problems.
You may also have problems converting a task to a multitask if your dependencies are set up incorrectly. Take the following example:
	task 'build' => ['compile_extensions', 'run_tests', 'generate_rdoc']
The unit tests can't run if the compiled extensions aren't available, so
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
A Generic Project Rakefile
Inhaltsvorschau
Credit: Stefan Lang
Every project's Rakefile is different, but most Ruby projects can be handled by very similar Rakefiles. To close out the chapter, we present a generic Rakefile that includes most of the tasks covered in this chapter, and a few (such as compilation of C extensions) that we only hinted at.
This Rakefile will work for pure Ruby projects, Ruby projects with C extensions, and projects that are only C extensions. It defines an overarching task called publish that builds the project, runs tests, generates RDoc, and releases the whole thing on Ruby-Forge. It's a big file, but you don't have to use all of it. The publish task is made entirely of smaller tasks, and you can pick and choose from those smaller tasks to build your own Rakefile. For a simple project, you can just customize the settings at the beginning of the file, and ignore the rest. Of course, you can also extend this Rakefile with other tasks, like the stats task presented in Recipe 19.5.
This Rakefile assumes that you follow the directory layout conventions laid down by the setup.rb script, even if you don't actually use setup.rb to install your project. For instance, it assumes you put your Ruby files in lib/ and your unit tests in test/.
First, we include Rake libraries that make it easy to define certain kinds of tasks:
	# Rakefile

	require "rake/testtask"

	require "rake/clean"

	require "rake/rdoctask"

	require "rake/gempackagetask"
You'll need to configure these variables:
	# The name of your project

	PROJECT = "MyProject"



	# Your name, used in packaging.

	MY_NAME = "Frodo Beutlin"



	# Your email address, used in packaging.

	MY_EMAIL = "frodo.beutlin@my.al"



	# Short summary of your project, used in packaging.

	PROJECT_SUMMARY = "Commandline program and library for …"



	# The project's package name (as opposed to its display name). Used for

	# RubyForge connectivity and packaging.

	UNIX_NAME = "my_project"



	# Your RubyForge user name.

	RUBYFORGE_USER = ENV["RUBYFORGE_USER"] || "frodo"



	# Directory on RubyForge where your website's files should be uploaded.

	WEBSITE_DIR = "website"



	# Output directory for the rdoc html files.

	# If you don't have a custom homepage, and want to use the RDoc

	# index.html as homepage, just set it to WEBSITE_DIR.

	RDOC_HTML_DIR = "#{WEBSITE_DIR}/rdoc"
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Chapter 20: Multitasking and Multithreading
Inhaltsvorschau
You can't concentrate on more than What's six times nine? one thing at once. You won't get very far reading this book if someone is interrupting you every five seconds asking you to do arithmetic problems. But any computer with a modern operating system can do many things at once. More precisely, it can simulate that ability by switching very quickly back and forth between tasks.
In a multitasking operating system, each program, or process, gets its own space in memory and a share of the CPU's time. Every time you start the Ruby interpreter, it runs in a new process. On Unix-based systems, your script can spawn subprocesses: this feature is very useful for running external command-line programs and using the results in your own scripts (see Recipes 20.8 and 20.9, for instance).
The main problem with processes is that they're expensive. It's hard to read while people are asking you to do arithmetic, not because either activity is particularly difficult, but because it takes time to switch from one to the other. An operating system spends a lot of its time as overhead, switching between processes, trying to make sure each one gets a fair share of the CPU's time.
The other problem with processes is that it's difficult to get them to communicate with each other. For simple cases, you can use techniques like those described in Recipe 20.8. You can implement more complex cases with Inter-Process Communication and named pipes, but we say, don't bother. If you want your Ruby program to do two things at once, you're better off writing your code with threads.
A thread is a sort of lightweight process that runs inside a real process. One Ruby process can host any number of threads, all running more or less simultaneously. It's faster to switch between threads than to switch between processes, and since all of a process's threads run in the same memory space, they can communicate simply by sharing variables.
Recipe 20.3 covers the basics of multithreaded programming. We use threads throughout this book, except when only a subprocess will work (see, for instance, Recipe 20.1). Some recipes in other chapters, like Recipes 3.12 and 14.4, show threads used in context.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Running a Daemon Process on Unix
Inhaltsvorschau
You want to run a process in the background with minimal interference from users and the operating system.
In Ruby 1.9, you can simply call Process.daemon to turn the current process into a daemon. Otherwise, the most reliable way is to use the Daemonize module. It's not available as a gem, but it's worth downloading and installing, because it makes it easy and reliable to write a daemon:
	#!/usr/bin/ruby -w

	# 

daemonize_daemon.rb

	require 'tempfile'

	require 'daemonize'

	include Daemonize            # Import Daemonize::daemonize into this namespace



	puts 'About to daemonize.'

	daemonize                    # Now you're a daemon process!

	log = Tempfile.new('daemon.log')

	loop do

	  log.puts "I'm a daemon, doin' daemon things."

	  log.flush

	  sleep 5

	end
If you run this code at the command line, you'll get back a new prompt almost immediately. But there will still be a Ruby process running in the background, writing to a temporary file every five seconds:
	$ ./daemonize_daemon.rb

	About to daemonize.

	$ ps x | grep daemon

	4472 ?         S       0:00 ruby 

daemonize_daemon.rb

	4474 pts/2     S+      0:00 grep daemon



	$ cat /tmp/daemon.log4472.0

	I'm a daemon, doin' daemon things.

	I'm a daemon, doin' daemon things.

	I'm a daemon, doin' daemon things.
Since it runs an infinite loop, this daemon process will run until you kill it:
	$ kill 4472



	$ ps x | grep daemon

	 4569 pts/2    S+     0:00 grep daemon
A different daemon might run until some condition is met, or until it receives a Unix signal, or a "stop" message through some interface.
A daemon process is one that runs in the background, without any direct user interface at all. Servers are usually daemon processes, but you might also write a daemon to do monitoring or task scheduling.
Rather than replacing your process with a daemon process, you may want to spawn a daemon while continuing with your original work. The best strategy for this is to spawn a subprocess with Kernel#fork.
Ruby's fork implementation takes a code block to be run by the subprocess. The code defined after the block is run in the original process. So pass your daemonizing code into
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Creating a Windows Service
Inhaltsvorschau
Credit: Bill Froelich
You want to write a self-contained Ruby program for Windows that performs a task in the background.
Create a Windows service using the win32-service library, available as the win32-service gem.
Put all the service code below into a Ruby file called rubysvc.rb. It defines a service that watches for the creation of a file c:\findme.txt; if it ever finds that file, it immediately renames it.
The first step is to register the service with Windows. Running ruby rubysrvc.rb register will create the service.
	# rubysrvc.rb

	require 'rubygems'

	require 'win32/service'

	include Win32



	SERVICE_NAME = "RubySvc"

	SERVICE_DISPLAYNAME = "A Ruby Service"

	if ARGV[0] == "register"

	  # Start the service.

	  svc = Service.new

	  svc.create_service do |s|

	    s.service_name = SERVICE_NAME

	    s.display_name = SERVICE_DISPLAYNAME

	    s.binary_path_name = 'C:\InstantRails-1.3\ruby\bin\ruby ' +

	      File.expand_path($0)

	    s.dependencies = []

	  end

	  svc.close

	  puts "Registered Service - " + SERVICE_DISPLAYNAME
When you're all done, you can run rubysrvc.rb stop to stop the service and remove it from Windows:
	elsif ARGV[0] == "delete"

	  # Stop the service.

	  if Service.status(SERVICE_NAME).current_state == "running"

	    Service.stop(SERVICE_NAME)

	  end

	  Service.delete(SERVICE_NAME)

	  puts "Removed Service - " + SERVICE_DISPLAYNAME

	else
If you run rubysrvc.rb with no arguments, nothing will happen, but it will remind you what parameters you can use:
	if ENV["HOMEDRIVE"]!=nil

	  # We are not running as a service, but the user didn't provide any

	  # command line arguments. We've got nothing to do.

	  puts "Usage: ruby rubysvc.rb [option]"

	  puts "   Where option is one of the following:"

	  puts "       register - To register the Service so it " +

	       "appears in the control panel"

	  puts "       delete   - To delete the Service from the control panel"

	  exit

	end
But when Windows runs rubysrvc.rb as a service, the real action starts:
	# If we got this far, we are running as a service.

	class Daemon

	  def service_init

	    # Give the service time to get everything initialized and running,

	    # before we enter the service_main function.

	    sleep 10

	  end



	  def service_main

	    fileCount = 0 # Initialize the file counter for the rename

	    watchForFile = "c:\\findme.txt"

	    while state == RUNNING

	      sleep 5

	      if File.exists? watchForFile

	          fileCount += 1

	          File.rename watchForFile, watchForFile + "." + fileCount.to_s

	        end

	      end

	    end

	  end

	  d = Daemon.new

	  d.mainloop

	end
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Doing Two Things at Once with Threads
Inhaltsvorschau
You want your program to run two or more pieces of code in parallel.
Create a new thread by passing a code block into Thread.new. That block will run simultaneously with any code you write after the call to Thread.new.
The following code features two competing threads. One continually decrements a variable by one, while the main program's thread busily incrementing the same variable by three. The decrementing thread starts its work earlier, but the incrementing thread always wins in the end, because it increments the counter by a larger number:
	x = 0

	Thread.new do

	  while x < 5

	    x -= 1

	    puts "DEC: I decremented x to #{x}\n"

	  end

	  puts "DEC: x is too high; I give up!\n"

	end



	while x < 5

	  x += 3

	  puts "INC: I incremented x to #{x}\n"

	end

	# DEC: I decremented x to -1

	# DEC: I decremented x to -2

	# DEC: I decremented x to -3

	# DEC: I decremented x to -4

	# INC: I incremented x to -1

	# DEC: I decremented x to -2

	# INC: I incremented x to 1

	# DEC: I decremented x to 0

	# INC: I incremented x to 3

	# DEC: I decremented x to 2

	# INC: I incremented x to 5

	# DEC: x is too high; I give up!



	x                                # => 5
A Ruby process starts out running only one thread: the main thread. When you call Thread#new, Ruby spawns another thread and starts running it alongside the main thread. The operating system divides CPU time among all the running processes, and the Ruby interpreter further divides its alotted CPU time among all of its threads.
The block you pass into Thread.new is a closure (see Recipe 7.4), so it has access to all the variables that were in scope at the time you instantiated the thread. This means that threads can share variables; as a result, you don't need complex communication schemes the way you do to communicate between processes. However, it also means that your threads can step on each other's toes unless you're careful to synchronize any shared objects. In the example above, the threads were designed to step on each other's toes, providing head-to-head competition, but usually you don't want that.
Once a thread's execution reaches the end of its code block, the thread dies. If your main thread reaches the end of
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Synchronizing Access to an Object
Inhaltsvorschau
You want to make an object accessible from only one thread at a time.
Give the object a Mutex member (a semaphore that controls whose turn it is to use the object). You can then use this to synchronize activity on the object.
This code gives every object a synchronize method. This simulates the behavior of Java, in which synchronize is a keyword that can be applied to any object:
	require 'thread'

	class Object

	  def synchronize

	    mutex.synchronize { yield self }

	  end



	  def mutex

	    @mutex ||= Mutex.new

	  end

	end
Here's an example. The first thread gets a lock on the list and then dawdles for a while. The second thread is ready from the start to add to the list, but it doesn't get a chance until the first thread releases the lock.
	list = []

	Thread.new { list.synchronize { |l| sleep(5); 3.times { l.push "Thread 1" } } }

	Thread.new { list.synchronize { |l| 3.times { l.push "Thread 2" } } }

	sleep(6)

	list

	# => ["Thread 1", "Thread 1", "Thread 1", "Thread 2", "Thread 2", "Thread 2"]
Object#synchronize only prevents two synchronized code blocks from running at the same time. Nothing prevents a wayward thread from modifying the object without calling synchronize first:
	list = []

	Thread.new { list.synchronize { |l| sleep(5); 3.times { l.push "Thread 1" } } }

	Thread.new { 3.times { list.push "Thread 2" } }

	sleep(6)

	list

	# => ["Thread 2", "Thread 2", "Thread 2", "Thread 1", "Thread 1", "Thread 1"]
One of the big advantages of multithreaded programs is that different threads can share data. But where there is data sharing, there is the possibility for corruption. When two threads operate on the same object at the same time, the results can vary wildly depending on when the Ruby interpreter decides to switch between threads. To get predictable behavior, you need to have one thread lock the object, so other threads can't use it.
When every object has a synchronize method, it's easier to share an object between threads: if you want to work alone with the object, you put that code within a synchronize block. Of course, you may find yourself constantly writing synchronization code whenever you call certain methods of an object.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Terminating a Thread
Inhaltsvorschau
You want to kill a thread before the end of the program.
A thread terminates if it reaches the end of its code block. The best way to terminate a thread early is to convince it to reach the end of its code block. This way, the thread can run cleanup code before dying.
This thread runs a loop while the instance variable continue is true. Set this variable to false, and the thread will die a natural death:
	require 'thread'



	class CounterThread < Thread

	  def initialize

	    @count = 0

	    @continue = true



	    super do

	      @count += 1 while @continue

	      puts "I counted up to #{@count} before I was cruelly stopped."

	    end

	  end



	  def stop

	    @continue = false

	  end

	end



	counter = CounterThread.new

	sleep 2

	counter.stop

	# I counted up to 3413544 before I was cruelly stopped.
If you need to stop a thread that doesn't offer a stop-like function, or you need to stop an out-of-control thread immediately, you can always call Thread#terminate. This method stops a thread in its tracks:
	t = Thread.new { loop { puts 'I am the unstoppable thread!' } }

	# I am the unstoppable thread!

	# I am the unstoppable thread!

	# I am the unstoppable thread!

	# I am the unstoppable thread!

	t.terminate
It's better to convince someone they should do something than to force them to do it. The same is true of threads. Calling Thread.terminate is a bit like throwing an exception: it interrupts the normal flow of execution in an unpredictable place. Worse, there's no equivalent of a begin/ensure construct for thread termination, so calling Thread.terminate may corrupt your data or leave your program in an inconsistent state. If you plan to stop a thread before the program is over, you should build that capability into the thread object itself.
A common type of thread implements a loop: threads that process requests from a queue, or that periodically poll for new data. In these, the end of an iteration forms a natural stopping point. These threads can benefit from some simple VCR-style controls: pause, unpause, and stop.
Here's a Thread subclass which implements a loop that can be paused or stopped in a predictable way. A code block passed into the
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Running a Code Block on Many Objects Simultaneously
Inhaltsvorschau
Rather than iterating over the elements of a data structure one at a time, you want to run some function on all of them simultaneously.
Spawn a thread to handle each element of the data structure.
Here's a simple equivalent of Enumerable#each that runs a code block against every element of a data structure simultaneously. It returns the Thread objects it spawned so that you can pause them, kill them, or join them and wait for them to finish:
	module Enumerable

	  def each_simultaneously

	    threads = []

	    each { |e| threads >> Thread.new { yield e } }

	    return threads

	  end

	end
Running the following high-latency code with Enumerable#each would take 15 seconds. With our new Enumerable#each_simultaneously, it takes only five seconds:
	start_time = Time.now

	[7,8,9].each_simultaneously do |e|

	   sleep(5) # Simulate a long, high-latency operation

	   print "Completed operation for #{e}!\n"

	end

	# Completed operation for 8!

	# Completed operation for 7!

	# Completed operation for 9!

	Time.now - start_time                 # => 5.009334
You can save time by doing high-latency operations in parallel, since it often means you pay the latency price only once. If you're doing nameserver lookups, and the nameserver takes five seconds to respond to a request, you're going to be waiting at least five seconds. If you need to do 10 nameserver lookups, doing them in series will take 50 seconds, but doing them all at once might only take 5.
This technique can also be applied to the other methods of Enumerable. You could write a collect_simultaneously, a find_all_simultaneously, and so on. But that's a lot of methods to write. All the methods of Enumerable are based on each. What if we could just convince those methods to use each_simultaneously instead of each?
It would be too much work to replace all the existing methods of Enumerable, but we can swap out an individual Enumerable object's each implementation for another, by wrapping it in an Enumerable::Enumerator. Here's how it would work:
	require 'enumerator'



	array = [7, 8, 9]

	simultaneous_array = array.enum_for(:each_simultaneously)

	simultaneous_array.each do |e|

	  sleep(5) # Simulate a long, high-latency operation

	  print "Completed operation for #{e}!\n"

	end

	# Completed operation for 7!

	# Completed operation for 9!

	# Completed operation for 8!
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Limiting Multithreading with a Thread Pool
Inhaltsvorschau
You want to process multiple requests in parallel, but you don't necessarily want to run all the requests simultaneously. Using a technique like that in Recipe 20.6 can create a huge number of threads running at once, slowing down the average response time. You want to set a limit on the number of simultaneously running threads.
You want a thread pool. If you're writing an Internet server and you want to service requests in parallel, you should build your code on top of the gserver module, as seen in Recipe 14.14: it has a thread pool and many TCP/IP-specific features. Otherwise, here's a generic ThreadPool class, based on code from gserver.
The instance variable @pool contains the active threads. The Mutex and the ConditionVariable are used to control the addition of threads to the pool, so that the pool never contains more than @max_size threads:
	require 'thread'



	class ThreadPool

	  def initialize(max_size)

	    @pool = []

	    @max_size = max_size

	    @pool_mutex = Mutex.new

	    @pool_cv = ConditionVariable.new

	end
When a thread wants to enter the pool, but the pool is full, the thread puts itself to sleep by calling ConditionVariable#wait. When a thread in the pool finishes executing, it removes itself from the pool and calls ConditionVariable#signal to wake up the first sleeping thread:
	def dispatch(*args)

	  Thread.new do

	    # Wait for space in the pool.

	    @pool_mutex.synchronize do

	      while @pool.size >= @max_size

	        print "Pool is full; waiting to run #{args.join(',')}…\n" if $DEBUG

	        # Sleep until some other thread calls @pool_cv.signal.

	        @pool_cv.wait(@pool_mutex)

	      end

	    end
The newly-awakened thread adds itself to the pool, runs its code, and then calls ConditionVariable#signal to wake up the next sleeping thread:
	      @pool << Thread.current

	      begin

	        yield(*args)

	      rescue => e

	        exception(self, e, *args)

	      ensure

	        @pool_mutex.synchronize do

	          # Remove the thread from the pool.

	          @pool.delete(Thread.current)

	          # Signal the next waiting thread that there's a space in the pool.

	          @pool_cv.signal

	        end

	      end

	    end

	  end



	  def shutdown

	    @pool_mutex.synchronize { @pool_cv.wait(@pool_mutex) until @pool.empty? }

	  end



	  def exception(thread, exception, *original_args)

	    # Subclass this method to handle an exception within a thread.

	    puts "Exception in thread #{thread}: #{exception}"

	  end

	end
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Driving an External Process with popen
Inhaltsvorschau
You want to execute an external command in a subprocess. You want to pass some data into its standard input stream, and read its standard output.
If you don't care about the standard input side of things, you can just use the %x{} construction. This runs a string as a command in an operating system subshell, and returns the standard output of the command as a string.
	%x{whoami}                                           # => "leonardr\n"

	puts %x{ls -a empty_dir}

	# .

	# ..
If you want to pass data into the standard input of the subprocess, do it in a code block that you pass into the IO. popen method. Here's IO.popen used on a Unix system to invoke tail, a command that prints to standard output the last few lines of its standard input:
	IO.popen('tail -3', 'r+') do |pipe|

	  1.upto(100) { |i| pipe >> "This is line #{i}.\n" }

	  pipe.close_write

	  puts pipe.read

	end

	# This is line 98.

	# This is line 99.

	# This is line 100.
IO.popens pawns a subprocess and creates a pipe: an IO stream connecting the Ruby interpreter to the subprocess. IO.popen makes the pipe available to a code block, just as File.open makes an open file available to a code block. Writing to the IO object sends data to the standard input of the subprocess; reading from it reads data from its standard output.
IO.popen takes a file mode, just like File.open. To use both the standard input and output of a subprocess, you need to open it in read-write mode ("r+").
A command that accepts standard input won't really start running until its input stream is closed. If you use popen to run a command like tail, you must call pipe. close_write before you read from the pipe. If you try to read the subprocess' standard output while the subprocess is waiting for you to send it data on standard input, both processes will hang forever.
The %{} construct and the popen technique work on both Windows and Unix, but scripts that use them won't usually be portable, because it's very unlikely that the command you're running exists on all platforms.
On Unix systems, you can also use popen to spawn a Ruby subprocess. This is like calling
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Capturing the Output and Error Streams from a Unix Shell Command
Inhaltsvorschau
You want to run an external program as in Recipe 20.8, but you also want to capture the standard error stream. Using popen only gives you access to the standard output.
Use the open3 library in the Ruby standard library. Its popen3 method takes a code block, to which it passes three IO streams: one each for standard input, output, and error.
Suppose you perform the Unix ls command to list a nonexistent directory. ls will rightly object to this and write an error message to its standard error stream. If you invoked ls with IO.popen or the %x{} construction, that error message is passed right along to the standard error stream of your Ruby process. You can't capture it or suppress it:
	%x{ls no_such_directory}

	# ls: no_such_directory: No such file or directory
But if you use popen3, you can grab that error message and do whatever you want with it:
	require 'open3'



	Open3.popen3('ls -l no_such_directory') { |stdin, stdout, stderr| stderr.read }

	# => "ls: no_such_directory: No such file or directory\n"
The same caveats in the previous recipe apply to the IO streams returned by popen3. If you're running a command that accepts data on standard input, and you read from stdout before closing stdin, your process will hang.
Unlike IO.popen, the popen3 method is only implemented on Unix systems. However, the win32-open3 package (part of the Win32Utils project) provides a popen3 implementation.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Controlling a Process on Another Machine
Inhaltsvorschau
You want to run a process on another machine, controlling its input stream remotely, and reading its output and error streams.
The ruby-ssh gem, first described in Recipe 14.10, provides a popen3 method that works a lot like Ruby's built-in popen3, except that the process you spawn runs on another computer.
Here's a method that runs a Unix command on another computer and yields its standard I/O streams to a code block on your computer. All traffic going between the computers is encrypted with SSL. To authenticate yourself against the foreign host, you'll either need to provide a username and password, or set up an SSL key pair ahead of time.
	require 'rubygems'

	require 'net/ssh'



	def run_remotely(command, host, args)

	  Net::SSH.start(host, args) do |session|

	    session.process.popen3(command) do |stdin, stdout, stderr|

	      yield stdin, stdout, stderr

	    end

	  end

	end
Here it is in action:
	run_remotely('ls -l /home/leonardr/dir', 'example.com', :username=>'leonardr',

	             :password => 'mypass') { |i, o, e| puts o.read }

	# -rw-rw-r-- 1 

leonardr leonardr      33 Dec 29 20:40 file1

	# -rw-rw-r-- 1   leonardr leonardr     102 Dec 29 20:40 file2
The Net::SSH library implements a low-level interface to the SSH protocol, but most of the time you don't need all that power. You just want to use SSH as a way to spawn and control processes on a remote computer. That's why Net:SSH also provides a popen3 interface that looks a lot like the popen3 you use to manipulate processes on your own computer.
Apart from the issue of authentication, there are a couple of differences between Net::SSH.popen3 and Open3.popen3. With Open3.popen3, you must be careful to close the standard input stream before reading from the output or error streams. With the Net::SSH version of popen3, you can read from the output or error streams as soon as the process writes any data to it. This lets you interleave stdin writes and stdout reads:
	run_remotely('cat', 'example.com', :username=>'leonardr',

	             :password => 'mypass') do |stdin, stdout, stderr|

	  stdin.puts 'Line one.'

	  puts stdout.read

	  stdin.puts 'Line two.'

	  puts stdout.read

	end

	# "Line one."

	# "Line two."
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Avoiding Deadlock
Inhaltsvorschau
Your threads are competing for exclusive access to the same resources. With no coordination between threads, you'll end up with deadlock. Thread A will be blocking, waiting for a resource held by thread B, and thread B will be blocking, waiting for a resource held by thread A. Neither thread will ever be seen again.
There's no simple mix-in solution to this problem. You need to come up with some rules for how your threads acquire locks, and make sure your code always abides by them.
Basically, you need to guarantee that all your threads acquire locks in the same order. Impose an ordering (formally or informally) on all the locks in your program and make sure that your threads always acquire locks in ascending numerical order.
Here's how it would work. The standard illustration of deadlock is the Dining Philosophers problem. A table of philosophers are sharing a plate of rice and some chopsticks, but there aren't enough utensils to go around. When there are only two chopsticks, it's easy to see the problem. If philosopher A is holding one chopstick (that is, has a lock on it), and philosopher B is holding the other, then nobody can eat.
In this scenario, you'd designate the the lock on one chopstick as lock #1, and the lock on the other chopstick as lock #2. If you guarantee that no philosopher will pick up chopstick #2 unless they're already picked up the chopstick #1, deadlock is impossible. You can guarantee this by simply making all the philosophers implement the same behavior:
	require 'thread'

	$chopstick1 = Mutex.new

	$chopstick2 = Mutex.new



	class Philosopher < Thread

	  def initialize(name)

	    super do

	      loop do

	        $chopstick1.synchronize do

	          puts "#{name} has picked up one chopstick."

	          $chopstick2.synchronize do

	            puts "#{name} has picked up two chopsticks and eaten a " +

	                 "bite of tasty rice."

	          end

	        end

	      end

	    end

	  end

	end

	Philosopher.new('Moore')

	Philosopher.new('Anscombe')

	# Moore has picked up one chopstick.

	# Moore has picked up two chopsticks and eaten a bite of tasty rice.

	# Anscombe has picked up one chopstick.

	# Anscombe has picked up two chopsticks and eaten a bite of tasty rice.

	# Moore has picked up one chopstick.

	# Moore has picked up two chopsticks and eaten a bite of tasty rice.

	# …
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Chapter 21: User Interface
Inhaltsvorschau
Ruby has libraries for attaching programs to the three main types of user interface. The web interface, Ruby's most popular, is covered in depth in Chapters 15, 16, and (to a lesser extent) 14. This chapter covers the other two interfaces: the terminal or console interface, and the graphical ( GUI) interface. We also cover some unorthodox interfaces (Recipe 21.11).
The terminal interface is is a text-based interface usually invoked from a command line. It's used by programs like irb and the Ruby interpreter itself. The terminal interface is usually seen on Unix systems, but all modern operating systems support it.
In the classic Unix-style "command-line program," the user interface consists of the options used to invoke the program (Recipe 21.3); and the program's standard input, output, and error streams (Recipe 21.1; also see Recipe 6.16). The Ruby interpreter is a good example of this kind of program. You can invoke the ruby program with arguments like -d and --version, but once the interpreter starts, your options are limited to typing in a Ruby program and executing it.
The advantage of this simple interface is that you can use Unix shell tools like redirection and pipes to connect these programs to each other. Instead of manually typing a Ruby program into the interpreter's standard input, you can send it a file with the Unix command ruby < file.rb. If you've got another program that generates Ruby code and prints it to standard output, you can pipe the generated code into the interpreter with generator | ruby.
The disadvantage is that these programs are not very user-friendly. Libraries like Curses (Recipe 21.5), Readline, and HighLine can add color and sophistication to your terminal programs. The irb interactive interpreter uses Readline to offer interactive line editing instead of the simpler interface offered by the Unix shell (Recipe 21.10).
The graphical user interface is the most common interface in the world. Even a web interface is usually interpreted within a GUI on the client end. However, there's not much that's Ruby-specific about GUI programming. All the common GUI libraries (like Tk, GTK, and QT) are written in C, and Ruby's bindings to them look a lot like the bindings for other dynamic languages such as Perl and Python.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Inhaltsvorschau
HighLine, written by James Edward Gray II and Gregory Brown, is available as the highline gem. The Curses and Readline libraries come preinstalled with Ruby (even on Windows, if you use the one-click installer). If you're using Windows and don't have Curses, you can get the library and the Ruby bindings from http://www.dave.burt.id.au/ruby/curses.zip.
Ncurses is an improved version of Curses (allowing things like colored text), and most modern Unix systems have it installed. You can get Ncurses bindings for Ruby from http://ncurses-ruby.berlios.de/. It's also available as the Debian package libncurses-ruby.
The Tk binding for Ruby comes preinstalled with Ruby, assuming you've installed Tk itself. Ruby bindings for the most common GUI toolkits have been written:
wxRuby is interesting because it's cross-platform and uses native widgets on each platform. You can write a Ruby program with wxRuby that runs on Unix, Windows, and Mac OS X, and looks like a native application on all three platforms.
On Mac OS X, all the tools you need to build a Ruby GUI application come with the operating system, including a GUI builder. If you're using GTK, your life will be easier if you download the Glade GUI builder (http://glade.gnome.org/).
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Getting Input One Line at a Time
Inhaltsvorschau
You're writing an interactive console program, and you want to get line-based input from the user. You present the user with a prompt, and he types some data before hitting enter.
Instead of reading standard input all at once, read it a line at a time with gets or readline.
This method populates a data structure with values obtained from user input:
	def confirmation_hearings

	  questions = [['What is your name?', :name],

	               ['How old are you?', :age],

	               ['Why would you like to be Secretary of the Treasury?', :why]]

	  answers = questions.inject({}) do |answers, qv|

	    question, value = qv

	    print question + ' '

	    answers[value] = gets.chomp

	    answers

	  end

	  puts "Okay, you're confirmed!"

	  return answers

	end



	confirmation_hearings

	# What is your name?                                   # <= Leonard Richardson

	# How old are you?                                     # <= 27

	# Why would you like to be Secretary of the Treasury?  # <= Mainly for the money

	# Okay, you're confirmed!

	# => {:age=>"26", :why=>"Mainly for the money", :name=>"Leonard Richardson"}
Most console programs take their input from command-line switches or from a file passed in on standard input. This makes it easy to programatically combine console programs: you can pipe cat into grep into last without any of the programs having to know that they're connected to each other. But sometimes it's more user-friendly to ask for input interactively: in text-based games, or data entry programs with workflow.
The only difference between this technique and traditional console applications is that you're writing to standard output before you're completely done reading from standard input. You can pass an input file into a program like this, and it'll still work. In this example, a Ruby program containing the questionnaire code seen in the Solution is fed by an input file:
	$ ./confirmation_hearings.rb < answers

	# => What is your name? How old are you? Why would you like to be

	#    Secretary of the Treasury? Okay, you're confirmed!
The program works, but the result looks different—even though the standard output is actually the same. When a human is running the program, the newline created when they hit enter is echoed to the screen, making the second question appear on a separate line from the first. Those newlines don't get echoed when they're read from a file.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Getting Input One Character at a Time
Inhaltsvorschau
You're writing an interactive application or a terminal-based game. You want to read a user's input from standard input a single character at a time.
Most Ruby installations on Unix come with the the Curses extension installed. If Curses has the features you want to write the rest of your program, the simplest solution is to use it.
This simple Curses program echoes every key you type to the top-left corner of the screen. It stops when you hit the escape key (\e).
	#!/usr/bin/ruby -w

	# curses_single_char_input.rb

	require 'curses'

	include Curses



	# Setup: create a curses screen that doesn't echo its input.

	init_screen

	noecho



	# Cleanup: restore the terminal settings when the program is exited or

	# killed.

	trap(0) { echo }



	while (c = getch) != ?\e do

	  setpos(0,0)

	  addstr("You typed #{c.chr.inspect}")

	end
If you don't want Curses to take over your program, you can use the HighLine library instead (available as the highline gem). It does its best to define a get_ character method that will work on your system. The get_ character method itself is private, but you can access it from within a call to ask:
	require 'rubygems'

	require 'highline/import'



	while (c = ask('') { |q| q.character = true; q.echo = false }) != "\e" do

	  print "You typed #{c.inspect}"

	end
Be careful; ask echoes a newline after every character it receives. That's why I use a print statement in that example instead of puts.
Of course, you can avoid this annoyance by hacking the HighLine class to make get_character public:
	class HighLine

	  public :get_character

	end

	input = HighLine.new

	while (c = input.get_ 

character) != ?\e do

	  puts "You typed #{c.chr.inspect}"

	end
This is a huge and complicated problem that (fortunately) is completely hidden by Curses and HighLine. Here's the problem: Unix systems know how to talk to a lot of historic and modern terminals. Each one has a different feature set and a different command language. HighLine (through the Termios library it uses on Unix) and Curses hide this complexity.
Windows doesn't have to deal with a lot of terminal types, but Windows programs don't usually read from standard input either (much less one character at a time). To do single- character input on Windows, HighLine makes raw Windows API calls. Here's some code based on HighLine's, which you can use on Windows if you don't want to require HighLine:
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Parsing Command-Line Arguments
Inhaltsvorschau
You want to make your Ruby script take command-line arguments, the way most Unix utilities and scripts do.
If you want to treat your command-line arguments as a simple list of strings, you can just iterate over the ARGV array.
Here's a Ruby version of the Unix command cat; it takes a list of files on the command line, opens each one, and prints its contents to standard output:
	#!/usr/bin/ruby -w

	# cat.rb



	ARGV.each { |filename| IO.readlines(filename).each { |line| puts line } }
If you want to treat your command-line arguments as a list of files, and you plan to open each of those files and iterate over them line by line, you can use ARGF instead of eARGV. The following cat implementation is equivalent to the first one.
	#!/usr/bin/ruby -w

	# cat_argf.rb



	ARGF.each { |line| puts line }
If you want to treat certain command-line arguments as switches, or as anything other than a homogenous list of strings, use the OptionParser class in the optparse library. Don't write the argument parsing code yourself; there are too many edge cases to think about.
The OptionParser class can parse any command-line arguments you're likely to need, and it includes a lot of Unix know-how that would take a long time to write yourself. All you have to do is define the set of arguments your script accepts, and write code that reacts to the presence of each argument on the command line. Here, I'll use OptionParser to write cat2.rb, a second Ruby version of cat that supports a few of the real cat's command-line arguments.
The first phase is turning any command-line arguments into a data structure that I can easily consult during the actual program. The CatArguments class defined below is a hash that uses OptionParser to populate itself from a list of command-line arguments.
For each argument accepted by cat2.rb, I've added a code block to be run as a callback. When OptionParser sees a particular argument in ARGV, it runs the corresponding code block, which sets an appropriate value in the hash:
	#!/usr/bin/ruby

	# cat2.rb

	require 'optparse'



	class CatArguments < Hash

	  def initialize(args)

	    super()

	    self[:show_ends] = ''



	    opts = OptionParser.new do |opts|

	      opts.banner = "Usage: #$0 [options]"

	      opts.on('-E', '--show-ends [STRING]',

	              'display [STRING] at end of each line') do |string|

	        self[:show_ends] = string || '$'

	      end



	      opts.on('-n', '--number', 'number all output lines') do

	        self[:number_lines] = true

	      end



	      opts.on_tail('-h', '--help', 'display this help and exit') do

	        puts opts

	        exit

	      end

	    end



	    opts.parse!(args)

	  end

	end



	arguments = CatArguments.new(ARGV)
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Testing Whether a Program Is Running Interactively
Inhaltsvorschau
You want to see whether there's another person on the other end of your program, or whether the program has been hooked up to a file or the output of another program.
STDIN.tty? returns true if there's a terminal hooked up to your program's original standard input. Since only humans use terminals, this will suffice. This code works on Unix and Windows:
	#!/usr/bin/ruby -w

	# interactive_or_not.rb

	if STDIN.tty?

	  puts "Let me be the first to welcome my human overlords."

	else

	  puts "How goes the revolution, brother software?"

	end
Running this program in different ways gives different results:
	$ ./interactive_or_not.rb

	Let me be the first to welcome my human overlords.



	$ echo "Some data" | interactive_or_not.rb

	How goes the revolution, brother software?



	$ ./interactive_or_not.rb < input_file

	How goes the revolution, brother software?
An interactive application can be more user friendly than one that runs solely off its command-line arguments and input streams. By checking STDIN.tty? you can make your program have an interactive and a noninteractive mode. The noninteractive mode can be chained together with other programs or used in shell scripts.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Setting Up and Tearing Down a Curses Program
Inhaltsvorschau
To write a program that uses Curses or Ncurses, you have to write a lot of setup and cleanup code. You'd like to factor that out.
Here's a wrapper method that sets up the Curses library and passes the main screen object into a code block:
	require 'curses'



	module Curses

	  def self.program

	    main_screen = init_screen

	    noecho

	    cbreak

	    curs_set(0)

	    main_screen.keypad = true

	    yield main_screen

	  end

	end
Here's a simple Ruby program that uses the wrapper method to fill up the screen with random placements of a given string:
	Curses.program do |scr|

	  str = ARGV[0] || 'Test'

	  max_x = scr.maxx-str.size+1

	  max_y = scr.maxy

	  100.times do

	    scr.setpos(rand(max_y), rand(max_x))

	    scr.addstr(str)

	  end

	  scr.getch

	end
The initialization, which is hidden in Curses.program, does the following things:
  • Stops keystrokes from being echoed to the screen (noecho)
  • Hides the cursor (curs_set(0))
  • Turns off buffered input so keys can be processed as they're typed (cbreak)
  • Makes the keyboard's arrow keys generate recognizable key events (keypad=true)
The code is a little different if you're using the third-party ncurses binding instead of the curses library that comes with Ruby. The main difference is that with ncurses, you must write some of the cleanup code that the curses library handles automatically. A wrapper method is also a good place to set up the ncurses color code if you plan to use colored text (see Recipe 21.8 for more on this).
Here's an Ncurses.program method that's equivalent to Curses.program, except that it performs its cleanup manually by registering an at_exit block to run just before the interpreter exits. This wrapper also turns on color and initializes a few default color pairs. If your terminal has no color support, the color code will run but it won't do anything.
	require 'ncurses'



	module Ncurses

	  COLORS = [COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_YELLOW, COLOR_BLUE,

	            COLOR_MAGENTA, COLOR_CYAN, COLOR_WHITE]



	  def self.program

	    stdscr = Ncurses.initscr



	    # Run ncurses 

cleanup code when the program exits.

	    at_exit do

	      echo

	      nocbreak

	      curs_set(1)

	      stdscr.keypad(0)

	      endwin

	    end



	    noecho

	    cbreak

	    curs_set(0)

	    stdscr.keypad(1)

	    start_color



	    COLORS[1…COLORS.size].each_with_index do |color, i|

	      init_pair(i+1, color, COLOR_BLACK)

	    end



	    yield stdscr

	  end

	end
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Clearing the Screen
Inhaltsvorschau
You're writing a console application, and you want it to clear the screen.
Capture the output of the Unix clear command as a string and print it whenever you want to clear the screen:
	#!/usr/bin/ruby -w

	# clear_console.rb

	clear_code = %x{clear}



	puts 'Press enter to clear the screen.'

	$stdin.gets

	print clear_code

	puts "It's cleared!"
The clear command prints an escape code sequence to standard output, which the Unix terminal interprets as a clear-screen command. The exact string depends on your terminal, but it's probably an ANSI escape sequence, like this:
	%x{clear}                       # => "\e[H\e[2J"
Your Ruby script can print this escape code sequence to standard output, just as the clear command can, and clear the screen.
On Windows, the command is cls, and you can't just print its standard output to clear the screen. Every time you want to clear the screen, you need to call out to cls with Kernel#system:
	# clear_console_windows.rb



	puts 'Press enter to clear the screen.'

	$stdin.gets

	system('cls')

	puts "It's cleared!"
If you've made your Windows terminal support ANSI (see Recipe 21.8), then you can print the same ANSI escape sequence used on Unix.
The Curses library makes this a lot more straightforward. A Curses application can clear any of its windows with Curses::Window#clear. Curses::clear will clear the main window:
	#!/usr/bin/ruby -w

	# curses_clear.rb

	require 'curses'



	Curses.init_ 

screen

	Curses.setpos(0,0)

	Curses::addstr("Type all you want. 'C' clears the  

screen, Escape quits.\n")



	begin

	  c = nil

	  begin

	    c = Curses.getch

	  end until c == ?C or c == ?\e

	  Curses.clear

	end until c == ?\e
But, as always, Curses takes over your whole application, so you might want to just use the escape sequence trick.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Determining Terminal Size
Inhaltsvorschau
Within a terminal-based application, you want to find the size of the terminal: how many rows and columns are available for you to draw on.
This is easy if you're using the Curses library. This example uses the Curses.program wrapper described in Recipe 21.5:
	Curses.program do |scr|

	  max_y, max_x = scr.maxy, scr.maxx



	  scr.setpos(0, 0)

	  scr.addstr("Your terminal size is #{max_x}x#{max_y}. Press any key to exit.")

	  scr.getch

	end
It's a little less easy with Ncurses: you have to pass in two arrays to the underlying C libraries, and extract the numbers from the arrays. Again, this example uses the Ncurses wrapper from Recipe 21.5:
	Ncurses.program do |scr|

	  max_y, max_x = [], []

	  scr.getmaxyx(max_y, max_x)

	  max_y, max_x = max_y[0], max_x[0]



	  str = "Your 

terminal size is #{max_x}x#{max_y}. Press any key to exit."

	  scr.mvaddstr(0, 0, str)

	  scr.getch

	end
If you're not using a Curses-style library, it's not easy at all.
If you plan to simulate graphical elements on a textual terminal, subdivide it into virtual windows, or print justified output, you'll need to know the terminal's dimensions. For decades, the standard terminal size has been 25 rows by 80 columns, but modern GUIs and high screen resolutions let users create text terminals of almost any size. It's okay to enforce a minimum terminal size, but it's a bad idea to assume that the terminal is any specific size.
The terminal size is a very useful piece of information to have, but it's not an easy one to get. The Curses library was written to solve this kind of problem, but if you're willing to go into the operating system API, or if you're on Windows where Curses is not a standard feature, you can find the terminal size without letting a Curses-style library take over your whole application.
On Unix systems (including Mac OS X), you can make an ioctl system call to get the terminal size. Since you're calling out to the underlying operating system, you'll need to use strange constants and C-like structures to carry the response:
	TIOCGWINSZ = 0x5413                  # For an Intel processor

	# TIOCGWINSZ = 0x40087468            # For a PowerPC processor



	def terminal_size

	 rows, cols = 25, 80

	  buf = [ 0, 0, 0, 0 ].pack("SSSS")

	  if STDOUT.ioctl(TIOCGWINSZ, buf) >= 0 then

	    rows, cols, row_pixels, col_pixels = buf.unpack("SSSS")[0..1]

	  end

	  return rows, cols

	end



	terminal_size                        # => [21, 80]
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Changing Text Color
Inhaltsvorschau
You want to display multicolored text on the console.
The simplest solution is to use HighLine. It lets you enclose color commands in an ERb template that gets interpreted within HighLine and printed to standard output. Try this colorful bit of code to test the capabilities of your terminal:
	require 'rubygems'

	require 'highline/import'



	say(%{Here's some <%= color('dark red text', RED) %>.})

	say(%{Here's some <%= color('bright red text on a blue background',

	                                RED+BOLD+ON_BLUE) %>.})

	say(%{Here's some <%= 

color('blinking bright cyan  

text', CYAN+BOLD+BLINK) %>.})

	say(%{Here's some <%= GREEN+UNDERLINE %>underlined dark green text<%=CLEAR%>.})
Some of these features (particularly the blinking and underlining) aren't supported on all terminals.
The HighLine#color method encloses a display string in special command strings, which start with an escape character and a left square bracket:
	HighLine.new.color('Hello', HighLine::GREEN)

	# => "\e[32mHello\e[0m"
These are ANSI escape sequences. Instead of displaying the string "\e[32m", an ANSI-compatible terminal treats it as a command: in this case, a command to start printing characters in green-on-black. The string "\e[0m" tells the terminal to go back to white-on-black.
Most modern Unix terminals support ANSI escape sequences, including the Mac OS X terminal. You should be able to get green text in your irb session just by calling puts "\e[32mHello\e[0m" (try it!), but HighLine makes it easy to get color without having to remember the ANSI sequences.
Windows terminals don't support ANSI by default, but you can get it to work by loading ANSI.SYS (see below for a relevant Microsoft support article).
An alternative to HighLine is the Ncurses library. It supports color terminals that use a means other than ANSI, but these days, most color terminals get their color support through ANSI. Since Ncurses is much more complex than HighLine, and not available as a gem, you should only use Ncurses for color if you're already using it for its other features.
Here's a rough equivalent of the HighLine program given above. This program uses the
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Reading a Password
Inhaltsvorschau
You want to prompt the user for a password, or otherwise capture input without echoing it to the screen for all to see.
The ruby-password library makes this easy, but it's not available as a Ruby gem. The HighLine library is available as a gem, and it can do this almost as well. You just have to turn off the terminal echo feature:
	require 'rubygems'

	require 'highline/import'



	def get_password(prompt='Password: ')

	  ask(prompt) { |q| q.echo = false}

	end



	get_password("What's your password? ")

	# What's your password?

	# => "buddy"
In 2000, President Bill Clinton signed into law the Electronic Signatures Bill, which makes electronic signatures as binding as handwritten signatures. He signed the law by hand and then signed it electronically. As he typed the password to his electronic signature, it was was echoed to the screen. Everyone in the world saw that his password was the name of his pet dog, Buddy. Don't let this happen to you: turn off echoing when gathering passwords.
Turning off echoing altogether is the safest way to gather a password, but it might make your users think your program has stopped responding to input. It's more userfriendly to echo a mask character, like an asterisk, for every character the user types. You can do this in HighLine by setting echo to the mask character instead of false:
	def get_password(prompt='Password: ', mask='*')

	  ask(prompt) { |q| q.echo = mask }

	end



	get_password

	# Password: *****

	# => "buddy"



	get_password('Password: ', false)

	# Password:

	# => "buddy"
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Allowing Input Editing with Readline
Inhaltsvorschau
You want to let your users edit their lines of input as they write them, the way irb does.
Use the readline library. Instead of reading directly from standard input, pass a prompt string into Readline.readline. The user will be able to edit their input using the same shortcut keys you can use in the irb Ruby interpreter (assuming their terminal supports those keys).
	#!/usr/bin/ruby -w

	# readline.rb

	require 'readline'

	vegetable = Readline.readline("What's your favorite vegetable?> ")

	puts "#{vegetable.capitalize}? Are you crazy?"
Note that you don't have to chomp the result of Readline.readline:
	$ ruby readline.rb

	What's your favorite vegetable?> okra

	Okra? Are you crazy?
On Windows, this isn't necessary because the cmd shell provides any console program with many of readline's features. The example given above will work on both Windows and Unix, but if you're writing a Windows-specific program, you don't need readline:
	# readline_windows.rb

	print "What's your favorite vegetable?> "

	puts gets.chomp.capitalize + "? Are you crazy?"
In a Unix program that accepts data from standard input, the user can use their backspace key to correct typing mistakes, one character at a time. Backspace is a control character: it's a real character, just like "1" and "m" (its Ruby string representation is "\010"), but it's not usually interpreted as data. Instead, it's treated as a command: it erases one character from the input buffer.
With the backspace key, you can correct errors one character at a time. But what if you want to insert text into the middle of a line, or delete the whole thing and start over? That's where readline comes in. It's a Ruby interface to the Readline library used by many Unix programs, and it recognizes many control characters besides the backspace.
In a readline program, you can use the left and right arrow keys to move back and forth in the input string before submitting it. If you're familiar with the Readline shortcut keys from Emacs or other Unix programs, you can perform more sophisticated text editing operations, including cut and paste.
The
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Making Your Keyboard Lights Blink
Inhaltsvorschau
You want to control the three standard keyboard LEDs (num lock, caps lock, and scroll lock) from a Ruby script.
Use the Blinkenlights library, available as the blinkenlights gem. It works on Windows or Linux (but not on Mac OS X), and it lets you toggle the lights individually or in patterns:
	require 'rubygems'

	require 'blinkenlights'



	# Turn individual 

lights on or off.

	BlinkenLights.open do |lights|

	  lights.left = true

	  lights.middle = true

	  lights.right = true



	  lights.scr = false

	  lights.cap = false

	  lights.num = false

	end



	# Display a light show.

	BlinkenLights.open do |lights|

	  lights.left_to_right

	  10.times { lights.random }

	  lights.right_to_left

	end
The keyboard lights are an often-overlooked user interface. They were originally designed to reflect information about the state of the keyboard itself, but they can be manipulated from the computer to display more interesting things. Each light can continually display one bit of information (such as whether you have new email), or can flash over time to indicate a rate (such as your computer's use of incoming or outgoing bandwidth).
BlinkenLights works by writing special command codes to the Unix keyboard device (/dev/tty8 is the default, but /dev/console should also work). Usually, you can only write to these devices when running as root.
On Windows, BlinkenLights works by sending key events that make Windows think you actually hit the corresponding key. This means that if you tell BlinkenLights on Windows to turn on your caps lock light, caps lock itself is also enabled. The state of the light can't be disconnected from the state of the keyboard.
When you pass a code block into Blinkenlights.open, BlinkenLights runs the block and then restores the original state of the lights. This avoids confusing those users who use their lights to keep track of the state of their keyboards. If you want your setting of the lights to persist until they're changed again, then use the return value of Blinkenlights.open instead of passing in a code block.
This code will turn on the first two lights to represent the number six in binary. Until they're changed again, whether through the keyboard or through code, they'll stay on. Even the end of your program won't restore the original state of the lights.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Creating a GUI Application with Tk
Inhaltsvorschau
Credit: Kevin Marshall
You need to create a program that has a graphical user interface (GUI).
Use the Tk library. It's language-independent, cross-platform, and best of all, it comes standard with most Ruby distributions.
With Tk you create GUI elements, or "widgets", and then bind code blocks to them. When something happens (like the user clicking a widget), Tk runs the appropriate code block.
Ruby provides a class for each type of Tk widget. This simple Tk program creates a "root" widget (the application window), and a "label" widget within the window. The program then waits for events (although it can't respond to any).
	require 'tk'

	root = TkRoot.new { title "Tiny Tk Application" }

	label = TkLabel.new(root) { text "You are a trout!" }

	label.pack

	Tk.mainloop
When run, it looks like Figure 21-1.
Figure 21-1: You are a trout
The simple application above shows most of the basic features of GUI programming in Tk and other modern GUI toolkits. We'll use the techniques to build a more complex application.
Tk GUI development and layout take a parent/child approach. Most widgets are children of other widgets: depending on the widget, this nesting can go arbitrarily deep. The exception to this rule is the TkRoot widget: it's always the top-level widget, and it's represented as the application window.
Child widgets are "packed" inside their parents so they can be displayed. A system called the geometry manager controls where on the screen the widgets actually show up. The default geometry manager is the "placer" manager, which lets you place widgets in relation to each other.
Tk applications are event-driven, so the final step is to start a main event loop which tells our program to listen for events to be fired on our widgets.
To further illustrate, let's make a simple stopwatch program to demostrate a realworld use of Tk.
To start, we'll create four simple methods that will be bound to our widgets. These are the nonGUI core of the program:
	#!/usr/bin/ruby

	# stopwatch.rb

	require 'tk'



	class Stopwatch



	  def start

	    @accumulated = 0 unless @accumulated

	    @elapsed = 0

	    @start = Time.now



	    @mybutton.configure('text' => 'Stop')

	    @mybutton.command { stop }

	    @timer.start

	  end



	  def stop

	    @mybutton.configure('text' => 'Start')

	    @mybutton.command { start }

	    @timer.stop

	    @accumulated += @elapsed

	  end



	  def reset

	    stop

	    @accumulated, @elapsed = 0, 0

	    @mylabel.configure('text' => '00:00:00.0')

	  end



	  def tick

	    @elapsed = Time.now - @start

	    time = @accumulated + @elapsed

	    h = sprintf('%02i', (time.to_i / 3600))

	    m = sprintf('%02i', ((time.to_i % 3600) / 60))

	    s = sprintf('%02i', (time.to_i % 60))

	    mt = sprintf('%1i', ((time - time.to_i)*10).to_i)

	    newtime = "#{h}:#{m}:#{s}:#{mt}"

	    @mylabel.configure('text' => newtime)

	  end
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Creating a GUI Application with wxRuby
Inhaltsvorschau
You want to write a portable GUI application that looks better than a Tk application.
Use the wxRuby library, available as a third-party download. It uses native GUI widgets on Windows, Unix, and Mac OS X. It's got many more features than the Tk library, and even greater complexity.
Here's a very simple wxRuby application (Figure 21-3):
	#!/usr/bin/ruby -w

	# wxtrout.rb



	require 'wxruby'

	class TroutApp < Wx::App

	  def on_init

	    frame = Wx::Frame.new(nil, -1, 'Tiny wxRuby Application')

	    panel = Wx::StaticText.new(frame, -1, 'You are a trout!',

	                               Wx::Point.new(-1,1), Wx::DEFAULT_SIZE,

	                               Wx::ALIGN_CENTER)

	    frame.show

	  end

	end



	TroutApp.new.main_loop
Figure 21-3: You are a wxRuby trout
The simple wxRuby application has the same basic structure as its Tk cousin (see Recipe 21.12). A top-level widget is created (here called a Frame) and a label (StaticText) widget is added to it. The application then goes into an event loop, listening for and retrieving events like mouse clicks.
A wxRuby version of the Tk stopwatch program is also similar, although much longer. wxRuby code tends to be more verbose and less idiomatic than Ruby Tk code.
The core methods are nearly unchanged, because they have little to do with the GUI:
	#!/usr/bin/ruby -w

	# wx_stopwatch.rb

	require 'wxruby'



	class StopwatchApp < Wx::App



	  def start

	    @start = Time.now

	    @button.set_label('Stop')

	    @button.refresh

	    @frame.evt_button(@button.get_id) { stop }

	    @timer.start(100) # The timer should tick every 100 milliseconds.

	  end



	  def stop

	    @button.set_label('Start')

	    @button.refresh

	    @frame.evt_button(@button.get_id) { start }

	    @timer.stop

	    @accumulated += @elapsed

	  end



	  def reset

	    stop

	    @accumulated, @elapsed = 0, 0

	    @label.set_label('00:00:00.0')

	    @frame.layout

	  end



	  def tick

	    @elapsed = Time.now - @start

	    time = @accumulated + @elapsed

	    h = sprintf('%02i', (time.to_i / 3600))

	    m = sprintf('%02i', ((time.to_i % 3600) / 60))

	    s = sprintf('%02i', (time.to_i % 60))

	    mt = sprintf('%1i', ((time - time.to_i)*10).to_i)

	    newtime = "#{h}:#{m}:#{s}:#{mt}"

	    @label.set_label(newtime)

	    @frame.layout

	  end
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Creating a GUI Application with Ruby/GTK
Inhaltsvorschau
You want to write a GUI application that uses the GTK widget library, perhaps so you can integrate it with the Gnome desktop environment.
Use the Ruby bindings to Gnome's GTK widget library, available as a third-party download. Here's a simple Ruby/GTK application (Figure 21-5).
	#!/usr/bin/ruby -w

	# 

gtktrout.rb

	require 'gtk2'



	Gtk.init

	window = Gtk::Window.new 'Tiny Ruby/GTK Application'

	label = Gtk::Label.new 'You are a trout!'

	window.add label

	window.signal_connect('destroy') { Gtk.main_quit }

	window.show_all

	Gtk.main
Figure 21-5: You are a GTK trout
Gnome is one of the two most popular Unix desktop suites. The Ruby-Gnome2 project provides and documents Ruby bindings to Gnome's vast array of C libraries. You can write Ruby applications that fully integrate with the Gnome desktop, but in this recipe I'm going to focus on the basics of the Gnome GUI library GTK.
Although the details are different, the sample program above is basically the same as it would be with Tk (Recipe 21.12) or the wxRuby library (Recipe 21.13). You create two widgets (a window and a label), attach the label to the window, and tell the GUI library to display the window. As with Tk and wxRuby, the application goes into a display loop, capturing user events like mouse clicks.
The sample program won't actually respond to any user events, though, so let's create a Ruby/GTK version of the stopwatch program seen in previous GUI recipes.
The core methods, the ones that actually implement the stopwatch, are basically the same as the corresponding methods in the Tk and wxRuby recipes. Since GTK doesn't have a timer widget, I've implemented a simple timer as a separate thread. The other point of interest is the HTML-like markup that GTK uses to customize the font size and weight of the stopwatch text.
	#!/usr/bin/ruby -w

	# gtk_stopwatch.rb

	require 'gtk2'



	class Stopwatch



	  LABEL_MARKUP = '<span font_desc="16" weight="bold">%s</span>'



	  def start

	    @accumulated ||= 0

	    @elapsed = 0

	    @start = Time.now



	    @mybutton.label = 'Stop'

	    set_button_handler('clicked') { stop }

	    @timer_stopped = false

	    @timer = Thread.new do

	      until @timer_stopped do

	        sleep(0.1)

	        tick unless @timer_stopped

	      end

	    end

	  end



	  def stop

	    @mybutton.label = 'Start'

	    set_button_handler('clicked') { start }

	    @timer_stopped = true

	    @accumulated += @elapsed

	  end



	  def reset

	    stop

	    @accumulated, @elapsed = 0, 0

	    @mylabel.set_markup(LABEL_MARKUP % '00:00:00.0')

	  end



	  def tick

	    @elapsed = Time.now - @start

	    time = @accumulated + @elapsed

	    h = sprintf('%02i', (time.to_i / 3600))

	    m = sprintf('%02i', ((time.to_i % 3600) / 60))

	    s = sprintf('%02i', (time.to_i % 60))

	    mt = sprintf('%1i', ((time - time.to_i)*10).to_i)

	    @mylabel.set_markup(LABEL_MARKUP % "#{h}:#{m}:#{s}:#{mt}")

	  end
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Creating a Mac OS X Application with RubyCocoa
Inhaltsvorschau
Credit: Alun ap Rhisiart
You want to create a native Mac OS X program with a graphical user interface.
Use the Mac OS X Cocoa library along with RubyCocoa and the Interface Builder application. RubyCocoa creates real OS X applications and provides a GUI interface for building GUIs, as opposed to other libraries, which make you define the GUI with Ruby code. RubyCocoa is a free download, and the Cocoa development tools are on the Mac OS X installation DVD.
Interface Builder is very powerful: you can create simple applications without writing any code. In fact, it takes longer to explain what to do than to do it. Here's how to create a simple application with Interface Builder:
  1. Start the Xcode application and create a new project from the File menu. Choose "Cocoa-Ruby Application" from the "New Project" list, hit the Next button, give your project a name and location on disk, and click Finish.
    XCode will create a project that looks like Figure 21-7.
    Figure 21-7: A new Cocoa-Ruby project
    The Cocoa-Ruby project template comes with two files: main.m (an Objective-C file) and rb_main.rb (a RubyCocoa file). For a simple application, this is all the code you need.
  2. Open the NIB Files group and doubleclick MainMenu.nib to open Interface Builder. You get a new application window, into which you can drag and drop GUI widgets, and a menubar labeled MainMenu.nib (English)–MainMenu.
    You'll also see a palette window with a selection of GUI objects; a nib document window named MainMenu.nib (English), containing classes, instances, images and sounds; and an inspector. If the inspector is not open, select Show Inspector from the Tools menu.
The screenshot in Figure 21-8 shows what we're going to do to our new application window (seen in the upper left).
Figure 21-8: Our destination Interface Builder screenshot
  1. Select the new application window and set the application's title. Type "Tiny RubyCocoa Application" in the inspector's Window Title field (you need to select the "Attributes" tab to see this field).
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Using AppleScript to Get User Input
Inhaltsvorschau
On Mac OS X, AppleScript makes it easy to add simple graphical interface elements to programs. You want to use AppleScript from a Ruby program.
Use the AppleScript library, written by John Butler and available as the applescript gem. It lets you talk to AppleScript from Ruby.
Here's a script that uses the AppleScript class to get input through AppleScript. It also shows off the AppleScript.say method, which uses Mac OS X's text-to-speech capabilities:
	require 'rubygems'

	require 'applescript'



	name = AppleScript.gets("What's your name?")



	AppleScript.puts("Thank you!")



	choice = AppleScript.choose("So which of these is your name?",

	                            ["Leonard", "Mike", "Lucas", name])



	if name == choice

	  AppleScript.say "You are right!"

	  picture = AppleScript.choose_file("Find a picture of yourself")



	  if File.exists?(picture)

	    AppleScript.say "Thanks, I will now post it on Flickr for you."

	    # Exercise for the reader: upload the file to Flickr

	  end

	else

	  AppleScript.say "But you just said your name was #{name}!"

	end
The AppleScript library is just a simple wrapper around the osascript command-line interface to AppleScript. If you already know AppleScript, you can execute raw AppleScript code with AppleScript.execute:
	script = 'tell application "Finder" to display dialog "Hello World!" ' +

	         'buttons {"OK"}'

	AppleScript.execute(script)
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Chapter 22: Extending Ruby with Other Languages
Inhaltsvorschau
When you decide to use an interpreted language such as Ruby, you're trading raw speed for ease of use. It's far easier to develop a program in a higher-level language, and you get a working program faster, but you sacrifice some of the speed you might get by writing the program in a lower-level language like C and C++.
That's the simplified view. Anyone who's spent any serious amount of time working with higher-level languages knows that the truth is usually more complex. In many situations, the tradeoff doesn't really matter: if the program is only going to be run once, who cares if it takes twice as long to do its job? If a program is complex enough, it might be prohibitively hard to implement in a low-level language: you might never actually get it working right without using a language like Ruby.
But even Ruby zealots must admit that there are still situations where it's useful to be able to call code written in another language. Maybe you need a particular part of your program to run blazingly fast, or maybe you want to use a particular library that's implemented in C or Java. When that happens you'll be grateful for Ruby's extension mechanism, which lets you call C code from a regular Ruby program; and the JRuby interpreter, which runs atop the Java Virtual Machine and uses Java classes as though they were Ruby classes.
Compared to other dynamic languages, it's pretty easy to write C extensions in Ruby. The interfaces you need to understand are easy to use and clearly defined in just a few header files, there are numerous examples available in the Ruby standard library itself, and there are even tools that can help you access C libraries without writing any C code at all.
So let's break out that trusty C compiler and learn how to drop down under the hood of the Ruby interpreter, because you just never know when your next program will to turn into one of those situations where a little bit of C code is the only solution to the problem.
—Garrett Rooney
Credit: Garrett Rooney
You want to implement part of your Ruby program in C. This might be the part of your program that needs to run really fast, it might contain some very platformspecific code, or you might just have a C implementation already, and you don't want to also write one in Ruby.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Writing a C Extension for Ruby
Inhaltsvorschau
Credit: Garrett Rooney
You want to implement part of your Ruby program in C. This might be the part of your program that needs to run really fast, it might contain some very platformspecific code, or you might just have a C implementation already, and you don't want to also write one in Ruby.
Write a C extension that implements that portion of your program. Compile it with extconf.rb and require it in your Ruby program as though it were a Ruby library. You'll need to have the Ruby header files installed on your system.
Here's a simple Ruby program that requires a library called example. It instantiates an instance of Example::Class from that library, and calls a method on that library:
	require 'example'

	e = Example::Class.new

	e.print_string("Hello World\n")

	# Hello World
What would the example library look like if it were written in Ruby? Something like this:
	# example.rb

	module Example

	  class Class

	    def print_string(s)

	      print s

	    end

	  end

	end
Let's implement that same functionality in C code. This small C library, example.c, defines a Ruby module, class, and method using the functions made available by ruby.h:
	#include <ruby.h>

	#include <stdio.h>



	static VALUE rb_mExample;

	static VALUE rb_cClass;



	static VALUE

	print_string(VALUE class, VALUE arg)

	{

	  printf("%s", RSTRING(arg)->ptr);

	  return Qnil;

	}

	void

	Init_example()

	{

	  rb_mExample = rb_define_module("Example");



	  rb_ 

cClass = rb_define_class_under(rb_mExample, "Class", rb_cObject);



	  rb_define_method(rb_cClass, "print_string", print_string, 1);

	}
To build the extension, you also need to create an extconf.rb file:
	# extconf.rb

	require 'mkmf'



	dir_config('example')

	create_makefile('example')
Then you can build your library by running extconf.rb, then make:
	$ ls

	example.c extconf.rb



	$ ruby extconf.rb

	creating Makefile



	$ make

	gcc -fPIC -Wall -g -O2 -fPIC -I. -I/usr/lib/ruby/1.8/i486-linux

	  -I/usr/lib/ruby/1.8/i486-linux -I. -c example



	gcc -shared -L"/usr/lib" -o example.so example.o -lruby1.8

	  -lpthread -ldl -lcrypt -lm -lc



	$ ls

	Makefile example.c example.o example.so extconf.rb
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Using a C Library from Ruby
Inhaltsvorschau
Credit: Garrett Rooney
You'd like to use a library in your Ruby program, but the library's implemented in C and there are no bindings.
Write a Ruby extension that wraps the C library with Ruby classes and methods.
Let's say we want to give a Ruby interface to C's file methods (yes, the File class already does this, but this makes a good example). We want to make it possible to open a disk file and read from it a byte at a time.
Just as in Recipe 22.1, you'll need a C file that implements the actual extension. This one is called stdio.c. It's got an Init_stdio function that defines a Ruby module (Stdio), a Ruby class (Stdio::File), and some methods for that class.
The file_allocate function corresponds to the Stdio::File constructor. Because it's a constructor, we must also define some hook functions to create and destroy the underlying resources (in this case, a filehandle and the memory it uses):
	#include "stdio.h"

	#include "ruby.h"



	static VALUE rb_mStdio;

	static VALUE rb_cStdioFile;



	struct file

	{

	  FILE *fhandle;

	};



	static VALUE

	file_allocate(VALUE klass)

	{

	  struct file *f = malloc(sizeof(*f));

	  f->fhandle = NULL;

	  return Data_Wrap_Struct(klass, file_mark, file_free, f);

	}



	static void

	file_mark(struct file *f)

	{

	}



	static void

	file_free(struct file *f)

	{

	  fclose(f->fhandle);

	  free(f);

	}
The file_open function implements the Stdio::File#open method:
	static VALUE

	file_open(VALUE object, VALUE fname)

	{

	  struct file *f;

	  Data_Get_Struct(object, struct file, f);

	  f->fhandle = fopen(RSTRING(fname)->ptr, "r");

	  return Qnil;

	}
file_readbyte implements the Stdio::File#readbyte method:
 

static VALUE

	file_readbyte(VALUE object)

	{

	  char buffer[2] = { 0, 0 };

	  struct file *f;



	  Data_Get_Struct(object, struct file, f);



	  if (! f->fhandle)

	    rb_raise(rb_eRuntimeError, "Attempt to read from closed file");



	  fread(buffer, 1, 1, f->fhandle);



	  return rb_str_new2(buffer);

	}
Finally, our Init_ method defines the Stdio module, the File class, and the three methods defined for the File class:
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Calling a C Library Through SWIG
Inhaltsvorschau
Credit: Garrett Rooney
You want to use a C library in your Ruby code, but you don't want to have to write any C code to do it.
Use SWIG to generate the C extension for you. SWIG is a programming tool that takes as its input a file containing the information about C functions. It produces source code that lets you access those C functions from a variety of programming languages, including Ruby.
All you you need to write is an interface file, containing the prototypes for the C functions you want to call. The interface file also contains a few directives to control things like the name of the resulting module. Process that file with the swig command-line tool, build your extension, and you're up and running.
Let's build a SWIG extension that lets Ruby access functions from the standard C library. It'll provide access to enough functionality that you can read data from one file and write it to another. In Recipe 22.1, we wrote the C code for a similar extension ourselves, but here we'll let SWIG do it.
First we'll need a SWIG interface file, libc.i:
	%module libc



	FILE *fopen(const char *, const char *);



	int fread(void *, size_t, size_t, FILE *);

	int fwrite(void *, size_t, size_t, FILE *);

	int fclose(FILE *);



	void *malloc(size_t);
This file specifies the name of our extension as "libc". For SWIG Ruby extensions, this means the extension will be named "libc", and the code will be contained in a Ruby module claled Libc. This file also provides the prototypes for the functions we're going to want to call.
You'll also need an extconf.rb program, similar to the one we used in the previous two recipes:
	# extconf.rb

	require 'mkmf'

	dir_config('tcl')

	dir_config('libc')

	create_makefile('libc')
To generate the C extension, we process the header file with the swig command-line tool. We then run Ruby's extconf.rb program to generate a makefile, and run make to compile the extension:
	$ swig -ruby libc.i

	$ ls

	extconf.rb libc.i libc_wrap.c



	$ ruby extconf.rb --with-tcl-include=/usr/include/tcl8.4

	creating Makefile



	$ make

	…



	$ ls

	Makefile extconf.rb libc.i libc.so libc_wrap.c libc_wrap.o
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Writing Inline C in Your Ruby Code
Inhaltsvorschau
Credit: Garrett Rooney
You want to implement small portions of your program in C without going to the trouble of creating a C extension to Ruby.
Embed C code right in your Ruby program, and let RubyInline (available as the rubyinline gem) create an extension automatically.
For example, if you want to use C's stdio functions to copy a file, you can write RubyInline code like this:
	#!/usr/bin/ruby -w

	# copy.rb

	require 'rubygems'

	require 'inline'



	class Copier

	inline do |builder|

	  builder.c <<END

	void copy_file(const char *source, const char *dest)

	{

	  FILE *source_f = fopen(source, "r");

	  if (!source_f)

	  {

	    rb_raise(rb_eIOError, "Could not open source : '%s'", source);

	  }



	  FILE *dest_f = fopen(dest, "w+");

	  if (!dest_f)

	  {

	    rb_raise(rb_eIOError, "Could not open destination : '%s'", dest);

	  }



	  char buffer[1024];



	  int nread = fread(buffer, 1, 1024, source_f);

	  while (nread > 0)

	  {

	    fwrite(buffer, 1, nread, dest_f);

	    nread = fread(buffer, 1, 1024, source_f);

	  }

	}

	END

	 end

	end
The C function copy_file now exists as an instance method of Copier:
	open('source.txt', 'w') { |f| f << 'Some text.' }

	Copier.new.copy_file('source.txt', 'dest.txt')

	puts open('dest.txt') { |f| f.read }
Run this Ruby script, and you'll see it copy the string "Some text." from source.txt to dest.txt.
RubyInline is a framework that lets you embed other languages inside your Ruby code. It defines the Module# inline method, which returns a builder object. You pass the builder a string containing code written in a language other than Ruby, and the builder transforms it into something that you can call from Ruby.
When given C or C++ code (the two languages supported in the default RubyInline install), the builder objects writes a small extension to disk, compiles it, and loads it. You don't have to deal with the compilation yourself, but you can see the generated code and compiled extensions in the .ruby_inline subdirectory of your home directory.
There are some limitations you should be aware of, though.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Using Java Libraries with JRuby
Inhaltsvorschau
Credit: Thomas Enebo
Java offers many class libraries that would be useful to a Ruby programmer; you'd like to use one of those libraries from within Ruby. A Java JDBC database may allow you to connect to a database for which Ruby has no connector. Or perhaps you need to use an obscure Java library that has no Ruby counterpart.
JRuby provides an alternate implementation of the Ruby programming language that runs atop the Java Virtual Machine. When you interpret a Ruby program with JRuby instead of using the default Ruby interpreter, you can load and use Java classes from within the Ruby code.
The first step to using JRuby is to install it:
  1. Download the latest copy of JRuby (see below for the address).
  2. Unzip the JRuby package into the directory where you'd like to install it.
  3. Add to your PATH environment variable the bin/ subdirectory of your JRuby installation.
  4. Unless you've already installed it, download the Java Runtime Environment from Sun's Java web site and install it. You'll need the JRE version 1.4.x or higher.
Now you can invoke the JRuby interpreter with the jruby command and use it to run Ruby code. Here's a simple example that imports and uses Java's built-in Random class:
	#!/usr/bin/env jruby

	# random.jrb

	require 'java'

	include_class 'java.util.Random'



	r = Random.new(123)

	puts "Some random number #{r.nextInt % 10}"

	r.seed = 456

	puts "Another random number #{r.nextInt % 10}"
Heres a run of this program:
	$ jruby random.jrb

	Some random number 9

	Another random number 0
JRuby generally behaves like Ruby. The jruby interpreter supports a common subset of Ruby's command-line options, and includes a subset of common core libraries. As JRuby is developed, it will eventually end up with all of Ruby's options and libraries.
The first step in a JRuby program is to load the Java support classes. If you don't do this, you can still use the JRuby interpreter, but you'll be limited to a subset of the Ruby core libraries: you might as well just use the C implementation.
The statement require ' java' updates Ruby's
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Chapter 23: System Administration
Inhaltsvorschau
Once you start using Ruby, you'll want to use it everywhere. Well, nothing's stopping you. This chapter shows you how to use Ruby in command-line programs that solve general everyday problems. It also demonstrates patterns that you can use to solve your own, more specific everyday problems.
System administration scripts are usually private scripts, disposable or lightly reusable. Ruby scripts are easy to write, so you can get the job done quickly and move on. You won't feel bad if your script is less rigorous than your usual work, and you won't feel invested in a huge program that you only needed once.
Ruby's syntax makes it easy to write, but for system administration, it's the libraries that make Ruby powerful. Most of the recipes in this chapter combine ideas from recipes elsewhere in the book to solve a real-world problem. The most commonly used idea is the Find.find technique first covered in Recipe 6.12. Recipes 23.5, 23.6, 23.7, 23.8, and 23.9 all give different twists on this technique.
The major new feature introduced in this chapter is Ruby's standard etc library. It lets you query a Unix system's users and groups. It's used in Recipe 23.10 to look up a user's ID given their username. Recipe 23.9 uses it to find a user's home directory and to get the members of Unix groups.
Although these recipes focus mainly on Unix system administration, Ruby is perhaps even more useful for Windows administration. Unix has a wide variety of standard shell tools and an environment that makes it easy to combine them. If Ruby and other high-level languages didn't exist, Unix administrators would still have tools like find and cut, and they'd use those tools like they did throughout the 1980s. On Windows, though, languages like Ruby are useful even for simple administration tasks: Ruby is easier to use than VBScript or batch files.
If you're trying to administer a Windows machine with Ruby, there are many third-party libraries that provide Ruby hooks into Windows internals: see especially the "win32utils" project at http://rubyforge.org/projects/win32utils/. Another useful library is Ruby's standard
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Scripting an External Program
Inhaltsvorschau
You want to automatically control an external program that expects to get terminal input from a human user.
When you're running a program that only needs a single string of input, you can use IO.popen, as described in Recipe 20.8. This method runs a command, sends it a string as standard input, and returns the contents of its standard output:
	def run(command, input='') 

IO.popen(command, 'r+') do |io|

	    io.puts input

	    io.close_write

	    return io.read

	   end

	end



	run 'wc -w', 'How many words are in this string?'      # => "7\n"
This technique is commonly used to invoke a command with sudo, which expects the user's password on standard input. This code obtains a user's password and runs a command on his behalf using sudo:
	print 'Enter your password for sudo: '

	sudo_password = gets.chomp

	run('sudo apachectl graceful', user_password)
IO.popen is a good way to run noninteractive commands—commands that read all their standard input at once and produce some output. But some programs are interactive; they send prompts to standard output, and expect a human on the other end to respond with more input.
On Unix, you can use Ruby's standard PTY and expect libraries to spawn a command and impersonate a human on the other end. This code scripts the Unix passwd command:
	require 'expect'

	require 'pty'

	

	print 'Old password:'

	old_pwd = gets.chomp



	print "\nNew password:"

	new_pwd = gets.chomp



	PTY.spawn('passwd') do |read,write,pid|

	  write.sync = true

	  $expect_verbose = false

	

	  # If 30 seconds pass and the expected text is not found, the

	  # response object will be nil.

	  read.expect("(current) UNIX password:", 30) do |response|

	    write.print old_pwd + "\n" if response

	  end



	  # You can use regular expressions instead of strings. The code block

	  # will give you the regex matches.

	  read.expect(/UNIX password: /, 2) do |response, *matches|

	    write.print new_pwd + "\n" if response

	  end



	  # The default value for the timeout is 9999999 seconds

	  read.expect("Retype new UNIX password:") do |response|

	    write.puts new_pwd + "\n" if response

	  end

	end
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Managing Windows Services
Inhaltsvorschau
Credit: Bill Froelich
You want to interact with existing system services on the Windows platform.
User the win32-service library, available as the gem of the same name. Its Service module gives you an interface to work with services in Windows 2000 or XP Pro.
You can use this to print a list of the currently running services on your machine:
	require 'rubygems'

	require 'win32/service'

	include Win32



	puts 'Currently Running 

Services:'

	Service.services do |svc|

	  if svc.current_state == 'running'

	    puts "#{svc.service_name}\t-\t#{svc.display_name}"

	  end

	end

	# Currently Running Services:

	# ACPI    -      Microsoft ACPI Driver

	# AcrSch2Svc     -       Acronis Scheduler2 Service

	# AFD     -      AFD Networking Support Environment

	# agp440  -      Intel AGP Bus Filter

	# …
This command checks whether the DNS client service exists on your machine:
	Service.exists?('dnscache')                    # => true
Service.status returns a Win32ServiceStatus struct describing the current state of a service:
	Service.status('dnscache')

	# => #<struct Struct::Win32ServiceStatus

	#      service_type="share process", current_state="running",

	#      controls_accepted=["netbind change", "param change", "stop"],

	#      win32_exit_code=0, service_specific_exit_code=0, check_point=0,

	#      wait_hint=0, :interactive?=false, pid=1144, service_flags=0>
If a service is not currently running, you can start it with Service.start:
	Service.stop('dnscache')

	Service.status('dnscache').current_state       # => "stopped"

	Service.start('dnscache')

	Service.status('dnscache').current_state       # => "running"
Services are typically accessed using their service_name attribute, not by their display name as shown in the Services Control Panel. Fortunately, Service provides helpful methods to convert between the two:
	Service.getdisplayname('dnscache')             # => "DNS Client"

	Service.getservicename('DNS Client')           # => "dnscache"
In addition to getting information about the status and list of services available, the win32-service
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Running Code as Another User
Inhaltsvorschau
While writing a Ruby script that runs as root, you need to take some action on behalf of another user: say, run an external program or create a file.
Simply set Process.euid to the UID of the user. When you're done, set it back to its previous value (that is, root's UID). Here's a method Process.as_uid that runs a code block under a different user ID and resets it at the end:
	module Process

	  def as_uid(uid)

	    old_euid, old_uid = Process.euid, Process.uid

	    Process.euid, Process.uid = uid, uid

	    begin

	      yield

	    ensure

	      Process.euid, Process.uid = old_euid, old_uid

	    end

	  end

	  module_function(:as_uid)

	end
When a Unix process tries to do something that requires special permissions (like access a file), the permissions are checked according to the "effective user ID" of the process. The effective user ID starts out as the user ID you used when you started the process, but if you're root you can change the effective user ID with Process.euid=. The operating system will treat you as though you were really that user.
This comes in handy when you're administering a system used by others. When someone asks you for help, you can write a script that impersonates them and runs the commands they don't know how to run. Rather than creating files as root and using chown to give them to another user, you can create the files as the other user in the first place.
Here's an example. On my system the account leonardr has UID 1000. When run as root, this code will create one directory owned by root and one owned by leonardr:
	Dir.mkdir("as_root")

	Process.as_uid(1000) do

	  Dir.mkdir("as_leonardr")

	  %x{whoami}

	end

	# => "leonardr\n"
Here are the directories:
	$ ls -ld as_*

	drwxr-xr-x 2 leonardr root 4096 Feb 2 13:06 as_leonardr/

	drwxr-xr-x 2 root root 4096 Feb 2 13:06 as_root/
When you're impersonating another user, your permissions are restricted to what that user can do. I can't remove the as_root directory as a nonroot user, because I created it as root:
	Process.as_uid(1000) do

	  Dir.rmdir("as_root")

	end

	# Errno::EPERM: Operation not permitted - as_root

	

	Dir.rmdir("as_root")                                 # => 0
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Running Periodic Tasks Without cron or at
Inhaltsvorschau
You want to write a self-contained Ruby program that performs a task in the background at a certain time, or runs repeatedly at a certain interval.
Fork off a new process that sleeps until it's time to run the Ruby code.
Here's a program that waits in the background until a certain time, then prints a message:
	#!/usr/bin/ruby

	# lunchtime.rb



	def background_run_at(time)

	  fork do

	    sleep(1) until Time.now >= time

	    yield

	  end

	end



	today = Time.now

	noon = Time.local(today.year, today.month, today.day, 12, 0, 0)

	raise Exception, "It's already past lunchtime!" if noon < Time.now



	background_run_at(noon) { puts "Lunchtime!" }
The fork command only works on Unix systems. The win32-process third-party add on gives Windows a fork implementation, but it's more idiomatic to run this code as a Windows service with win32-service.
With this technique, you can write self-contained Ruby programs that act as though they were spawned by the at command. If you want to run a backgrounded code block at a certain interval, the way a cronjob would, then combine fork with the technique described in Recipe 3.12.
	#!/usr/bin/ruby

	# reminder.rb

	def background_every_n_seconds(n)

	  fork do

	    loop do

	      before = Time.now

	      yield

	      interval = n-(Time.now-before)

	      sleep(interval) if interval > 0

	    end

	  end

	end



	background_every_n_seconds(15*60) { puts 'Get back to work!' }
Forking is the best technique if you want to run a background process and a foreground process. If you want a script that immediately returns you to the command prompt when it runs, you might want to use the Daemonize module instead; see Recipe 20.1.
  • Both the win32-process and the win32-service libraries are available at http://rubyforge.org/projects/win32utils/
  • Recipe 3.12, "Running a Code Block Periodically"
  • Recipe 20.1, "Running a Daemon Process on Unix"
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Deleting Files That Match a Regular Expression
Inhaltsvorschau
Credit: Matthew Palmer
You have a directory full of files and you need to remove some of them. The patterns you want to match are too complex to represent as file globs, but you can represent them as a regular expression.
The Dir.entries method gives you an array of all files in a directory, and you can iterate over this array with #each. A method to delete the files matching a regular expression might look like this:
	def delete_matching_regexp(dir, regex)

	  Dir.entries(dir).each do |name|

	    path = File.join(dir, name)

	    if name =~ regex

	      ftype = File.directory?(path) ? Dir : File

	      begin

	        ftype.delete(path)

	      rescue SystemCallError => e

	        $stderr.puts e.message

	      end

	    end

	  end

	end
Here's an example. Let's create a bunch of files and directories beneath a temporary directory:
	require ' 

fileutils'

	tmp_dir = 'tmp_buncha_files'

	files = ['A', 'A.txt', 'A.html', 'p.html', 'A.html.bak']

	directories = ['text.dir', 'Directory.for.html']



	Dir.mkdir(tmp_dir) unless File.directory? tmp_dir

	files.each { |f| FileUtils.touch(File.join(tmp_dir,f)) }

	directories.each { |d| Dir.mkdir(File.join(tmp_dir, d)) }
Now let's delete some of those files and directories. We'll delete a file or directory if its name starts with a capital letter, and if its extension (the string after its last period) is at least four characters long. This corresponds to the regular expression /^[A-Z].*\.[^.]{4,}$/:
	Dir.entries(tmp_dir)

	# => [".", "..", "A", "A.txt", "A.html", "p.html", "A.html.bak",

	#     "text.dir", "Directory.for.html"]



	delete_matching_regexp(tmp_dir, /^[A-Z].*\.[^.]{4,}$/)



	Dir.entries(tmp_dir)

	# => [".", "..", "A", "A.txt", "p.html", "A.html.bak", "text.dir"]
Like most good things in Ruby, Dir.entries takes a code block. It yields every file and subdirectory it finds to that code block. Our particular code block uses the regular expression match operator =~ to match every real file (no subdirectories) against the regular expression, and File.delete to remove offending files.
File.delete
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Renaming Files in Bulk
Inhaltsvorschau
You want to rename a bunch of files programmatically: for instance, to normalize the filename case or to change the extensions.
Use the Find module in the Ruby standard library. Here's a method that renames files according to the results of a code block. It returns a list of files it couldn't rename, because their proposed new name already existed:
	require 'find'

	

	module Find

	  def rename(*paths)

	    unrenamable = []

	    find(*paths) do |file|

	      next unless File.file? file # Skip directories, etc.

	      path, name = File.split(file)

	      new_name = yield name



	      if new_name and new_name != name

	        new_path = File.join(path, new_name)

	        if File.exists? new_path

	          unrenamable << file

	        else

	          puts " 

Renaming #{file} to #{new_path}" if $DEBUG

	          File.rename(file, new_path)

	        end

	      end

	    end

	    return unrenamable

	  end

	  module_function(:rename)

	end
This addition to the Find module makes it easy to do things like convert all filenames to lowercase. I'll create some dummy files to demonstrate:
	require 'fileutils'

	tmp_dir = 'tmp_files'

	Dir.mkdir(tmp_dir)

	['CamelCase.rb', 'OLDFILE.TXT', 'OldFile.txt'].each do |f|

	  FileUtils.touch(File.join(tmp_dir, f))

	end



	tmp_dir = File.join(tmp_dir, 'subdir')

	Dir.mkdir(tmp_dir)

	['i_am_SHOUTING', 'I_AM_SHOUTING'].each do |f|

	  FileUtils.touch(File.join(tmp_dir, f))

	end
Now let's convert these filenames to lowercase:
	$DEBUG = true

	Find.rename('./') { |file| file.downcase }

	# 

Renaming ./tmp_files/subdir/I_AM_SHOUTING to ./tmp_files/subdir/i_am_shouting

	# Renaming ./tmp_files/OldFile.txt to ./tmp_files/oldfile.txt

	# Renaming ./tmp_files/CamelCase.rb to ./tmp_files/camelcase.rb

	# => ["./OldFile.txt", "./dir/i_am_SHOUTING"]
Two of the files couldn't be renamed, because oldfile.txt and subdir/i_am_shouting were already taken.
Let's add a ".txt" extension to all files that have no extension:
	Find.rename('./') { |file| file + '.txt' unless file.index('.') }

	# 

Renaming ./tmp_files/subdir/i_am_shouting to ./tmp_files/subdir/i_am_shouting.txt

	#  

Renaming ./tmp_files/subdir/i_am_SHOUTING to ./tmp_files/subdir/i_am_SHOUTING.txt #

	# => []
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Finding Duplicate Files
Inhaltsvorschau
You want to find the duplicate files that are taking up all the space on your hard drive.
The simple solution is to group the files by size and then by their MD5 checksum. Two files are presumed identical if they have the same size and MD5 sum.
The following program takes a list of directories on the command line, and prints out all sets of duplicate files. You can pass a different code block into each_set_of_ duplicates for different behavior: for instance, to prompt the user about which of the duplicates to keep and which to delete.
	#!/usr/bin/ruby

	# find_duplicates.rb

	

	require 'find'

	require 'digest/md5'



	def each_set_of_duplicates(*paths)

	  sizes = {}

	  Find.find(*paths) do |f|

	   (sizes[File.size(f)] ||= []) << f if File.file? f

	  end

	  sizes.each do |size, files|

	    next unless files.size > 1

	    md5s = {}

	    files.each do |f|

	      digest = Digest::MD5.hexdigest(File.read(f))

	      (md5s[digest] ||= []) << f

	    end

	    md5s.each { |sum, files| yield files if files.size > 1 }

	  end

	end



	each_set_of_ 

duplicates(*ARGV) do |f|

	  puts " 

Duplicates: #{f.join(", ")}"

	end
This is one task that can't be handled with a simple Find.find code block, because it's trying to figure out which files have certain relationships to each other. Find.find takes care of walking the file tree, but it would be very inefficient to try to make a single trip through the tree and immediately spit out a set of duplicates. Instead, we group the files by size and then by their MD5 checksum.
The MD5 checksum is a short binary string used as a stand-in for the contents of a file. It's commonly used to verify that a huge file was downloaded without errors. It's not impossible for two different files to have an MD5 sum, but unless someone is deliberately trying to trick you, it's almost impossible to have two files with the same size and the same MD5 sum.
Calculating a MD5 sum is very expensive: it means performing a mathematical calculation on the entire contents of the file. Grouping the files by size beforehand greatly reduces the number of sums that must be calculated, but that's still a lot of I/O. Even if two similarly sized files differ in the first byte, the code above will read the entire files.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Automating Backups
Inhaltsvorschau
You want to make a dated archive of a directory to burn to CD or otherwise store on backup media.
This script copies a directory to a timestamped backup. It reuses the File.versioned_ filename method defined in Recipe 6.14, so you can create multiple backups in the same time period:
	require 'fileutils'



	def backup(from_dir, to_dir, time_format="-%Y%m%d")

	  from_path, from_name = File.split(from_dir)

	  now = Time.now.strftime(time_format)

	  Dir.mkdir(to_dir) unless File.exists? to_dir

	  unless File.directory? to_dir

	    raise ArgumentError, "Not a directory: #{to_dir}"

	  end

	  to = File.versioned_filename(File.join(to_dir, from_name + now))

	  FileUtils.cp_r(from_dir, to, :preserve=>true)

	  return to

	end



	# This method copied from "Backing Up to Versioned Filenames"

	class File

	  def File.versioned_filename(base, first_suffix=".0")

	    suffix = nil

	    filename = base

	    while File.exists?(filename)

	      suffix = (suffix ? suffix.succ : first_suffix)

	      filename = base + suffix

	    end

	    return filename

	  end

	end



	# Create a dummy directory

	Dir.mkdir('recipes')

	# And back it up.

	backup('recipes', '/tmp/backup')        # => "/tmp/backup/recipes-20061031"

	backup('recipes', '/tmp/backup')        # => "/tmp/backup/recipes-20061031.0"

	backup('recipes', '/tmp/backup', '-%Y%m%d-%H.%M.%S')

	# => "/tmp/backup/recipes-20061031-20.48.56"
The backup method recursively copies the contents of a directory into another directory, possibly on another filesystem. It uses the time-based scheme you specify along with versioned_filename to uniquely name the destination directory.
As written, the backup method uses a lot of space: every time you call it, it creates an entirely new copy of every file in the source directory. Fortunately, the technique has many variations. Instead of copying the files, you can make a timestamped tarball with the techniques from Recipe 12.10. You can archive the files to another computer with the techniques from Recipe 14.11 (although to save space, you should use the rsync program instead). You could even automatically check your work into a version control system every so often; this works better with text than with binary files.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Normalizing Ownership and Permissions in User Directories
Inhaltsvorschau
You want to make make sure your users' home directories don't contain world-writable directories, directories owned by other users, or other potential security problems.
Use the etc library to look up a user's home directory and UID from the username. Then use Find.find to walk the directory trees, and File methods to check and modify access to each file.
We are looking out for any case where one user's home directory can be modified by some other user. Whenever we find such a case, we fix it with a File.chmod or File.chown call. In this program, the actual calls are commented out, so that you don't accidentally change your permissions when you just want to test out the program.
	#!/usr/bin/ruby -w

	# normalize_homes.rb



	require 'etc'

	require 'find'

	require 'optparse'



	def normalize_home(pwd_entry, maximum_perms=0775, dry_run=true)

	  uid, home = pwd_entry.uid, pwd_entry.dir

	  username = pwd_entry.name



	  puts "Scanning #{username}'s home of #{home}."



	  Find.find(home) do |f|

	  next unless File.exists? f

	    stat = File.stat(f)

	    file_uid, file_gid, mode = stat.uid, stat.gid, stat.mode
The most obvious thing we want to check is whether the user owns every file in their home directory. With occasional exceptions (such as files owned by the web server), a user should own the files in his or her home directory:
	# Does the user own the file?

	if file_uid != uid

	  begin

	    current_owner = Etc.getpwuid(file_uid).name

	  rescue ArgumentError # No such user; just use UID

	    current_owner = "uid #{file_uid}"

	  end

	  puts " CHOWN #{f}"

	  puts " Current owner is #{current_owner}, should be #{username}"

	  # File.chown(uid, nil, f) unless dry_run

	end
A less obvious check involves the Unix group that owns the file. A user can let other people work on a file in their home directory by giving ownership to a user group. But you can only give ownership to a group if you're a member of that group. If a user's home directory contains a file owned by a group the user doesn't belong to, something fishy is probably going on.
	# Does the user belong to the group that owns the file?

	begin

	  group = Etc.getgrgid(file_gid)

	  group_name = group.name

	rescue ArgumentError # No such group

	  group_name = "gid #{file_gid}"

	end

	unless group && (group.mem.member?(username) || group.name == username)

	  puts " CHGRP #{f}"

	  puts " Current group is #{group_name}, and #{username} doesn't belong."

	  # File.chown(nil, uid, f) unless dry_run

	end
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Killing All Processes for a Given User
Inhaltsvorschau
You want an easy way to kill all the running processes of a user whose processes get out of control.
You can send a Unix signal (including the deadly SIGTERM or the even deadlier SIGKILL) from Ruby with the Process.kill method. But how to get the list of processes for a given user? The simplest way is to call out to the unix ps command and parse the output. Running ps -u#{username} gives us the processes for a particular user.
	#!/usr/bin/ruby -w

	# banish.rb

	def signal_all(username, signal)

	  lookup_uid(username)

	  killed = 0

	  %x{ps -u#{username}}.each_with_index do |proc, i|

	    next if i == 0                     # Skip the header provided by ps

	    pid = proc.split[0].to_i

	    begin

	      Process.kill(signal, pid)

	    rescue SystemCallError => e

	      raise e unless e.errno == Errno::ESRCH

	    end

	    killed += 1

	  end

	  return killed

	end
There are a couple things to look out for here.
  • ps dumps a big error message if we pass in the name of a nonexistent user. It would look better if we could handle that error ourselves. That's what the call to lookup_uid will do.
  • ps prints out a header as its first line. We want to skip that line because it doesn't represent a process.
  • Killing a process also kills all of its children. This can be a problem if the child process shows up later in the ps list: killing it again will raise a SystemCallError. We deal with that possibility by catching and ignoring that particular SystemCallError. We still count the process as "killed," though.
Here's the implementation of lookup_id:
	def lookup_uid(username)

	  require 'etc'

	  begin

	     user = Etc.getpwnam(username)

	  rescue ArgumentError

	    raise ArgumentError, "No such user: #{username}"

	  end

	  return user.uid

	end
Now all that remains is the command-line interface:
	require 'optparse'

	signal = "SIGHUP"

	opts = OptionParser.new do |opts|

	  opts.banner = "Usage: #{__FILE__} [-9] [USERNAME]"

	   opts.on("-9", "--with-extreme-prejudice",

	           "Send an uncatchable kill signal.") { signal = "SIGKILL" }

	end

	opts.parse!(ARGV)



	if ARGV.size != 1

	  $stderr.puts opts.banner

	  exit

	end



	username = ARGV[0]

	if username == "root"

	  $stderr.puts "Sorry, killing all of root's processes would bring down the system."

	  exit

	end

	puts "Killed #{signal_all(username, signal)} process(es)."
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
	

Zurück zu Ruby Cookbook


Themen

Buchreihen

Special Interest

International Sites

O'Reilly China O'Reilly USA O'Reilly Japan O'Reilly Taiwan