Logic

Method calls are statements. Ruby also provides a number of ways to make decisions that affect the repetition and order in which methods are invoked.

Control Structures

Ruby has all the usual control structures, such as if statements and while loops. Java, C, and Perl programmers may well get caught by the lack of braces around the bodies of these statements. Instead, Ruby uses the end keyword to signify the end of a body:

 if​ count > 10
  puts ​"Try again"
 elsif​ tries == 3
  puts ​"You lose"
 else
  puts ​"Enter a number"
 end

Similarly, while statements are terminated with end:

 while​ weight < 100 and num_pallets <= 30
  pallet = next_pallet()
  weight += pallet.​weight
  num_pallets += 1
 end

Ruby also contains variants of these statements. unless is like if, except that it checks for the condition to not be true. Similarly, until is like while, except that the loop continues until the condition evaluates to be true.

Ruby statement modifiers are a useful shortcut if the body of an if, unless, while, or until statement is a single expression. Simply write the expression, followed by the modifier keyword and the condition:

 puts ​"Danger, Will Robinson"​ ​if​ radiation > 3000
 distance = distance * 1.2 ​while​ distance < 100

Although if statements are fairly common in Ruby applications, newcomers to the Ruby language are often surprised to find that looping constructs are rarely used. Blocks and iterators often take their place.

Blocks and Iterators

Code blocks are chunks of code between braces or between doend. A common convention is that people use braces for single-line blocks and do/end for multiline blocks:

 { puts ​"Hello"​ } ​# this is a block
 
 do​ ​###
  club.​enroll​(person) ​# and so is this
  person.​socialize​ ​#
 end​ ​###

To pass a block to a method, place the block after the parameters (if any) to the method. In other words, put the start of the block at the end of the source line containing the method call. For example, in the following code, the block containing puts "Hi" is associated with the call to the greet method:

 greet { puts ​"Hi"​ }

If a method call has parameters, they appear before the block:

 verbose_greet(​"Dave"​, ​"loyal customer"​) { puts ​"Hi"​ }

A method can invoke an associated block one or more times by using the Ruby yield statement. You can think of yield as being something like a method call that calls out to the block associated with the method containing the yield. You can pass values to the block by giving parameters to yield. Within the block, you list the names of the arguments to receive these parameters between vertical bars (|).

Code blocks appear throughout Ruby applications. Often they’re used in conjunction with iterators—methods that return successive elements from some kind of collection, such as an array:

 animals = ​%w( ant bee cat dog elk )​ ​# create an array
 animals.​each​ {|animal| puts animal } ​# iterate over the contents

Each integer N implements a times method, which invokes an associated block N times:

 3.​times​ { print ​"Ho! "​ } ​#=> Ho! Ho! Ho!

The & prefix operator allows a method to capture a passed block as a named parameter:

 def​ ​wrap​ &b
  print ​"Santa says: "
  3.​times​(&b)
  print ​"​​ ​​"
 end
 wrap { print ​"Ho! "​ }

Within a block, or a method, control is sequential except when an exception occurs.

Exceptions

Exceptions are objects of the Exception class or its subclasses. The raise method causes an exception to be raised. This interrupts the normal flow through the code. Instead, Ruby searches back through the call stack for code that says it can handle this exception.

Both methods and blocks of code wrapped between begin and end keywords intercept certain classes of exceptions using rescue clauses:

 begin
  content = load_blog_data(file_name)
 rescue​ BlogDataNotFound
  STDERR.​puts​ ​"File ​​#{​file_name​}​​ not found"
 rescue​ BlogDataFormatError
  STDERR.​puts​ ​"Invalid blog data in ​​#{​file_name​}​​"
 rescue​ Exception => exc
  STDERR.​puts​ ​"General error loading ​​#{​file_name​}​​: ​​#{​exc.​message​​}​​"
 end

rescue clauses can be directly placed on the outermost level of a method definition without needing to enclose the contents in a begin/end block.

That concludes our brief introduction to control flow, and at this point you have the basic building blocks for creating larger structures.

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

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