Friday, 5 September 2008

Beginning Ruby By Peter Cooper - Part1

Yesterday i started reading Beginning Ruby Book By Peter Cooper.

I wanted to share few important quotations i found from the first 3 chapters from the book.

1) Kernel is a special class whose methods are made available in every class and scope throughout Ruby.The Kernel module in Ruby has no relationship to kernels in operating systems or the Linux kernel. As with a kernel and its operating system, the Kernel module is part of Ruby’s “core,” but there is no connection beyond that.

2) A question mark followed by a character returns an integer matching the position of that character in the ASCII table, a standard for representing characters as values.

3) You can embed expressions (and even logic) directly into strings. This process is called interpolation.In this situation, interpolation refers to the process of inserting the result of an expression into a string literal. The way to interpolate within a string is to place the expression within #{ and } symbols.

An even more basic example demonstrates:

puts "100 * 5 = #{100 * 5}"

You can interpolate other strings too:
x = "cat"

puts "The #{x} in the hat"

4) sub only does one substitution at a time, on the first instance of the text to match,whereas gsub does multiple substitutions at once, as this example demonstrates:

puts "this is a test".gsub('i', '')

5) More Examples of Regular Expressions

For example, let’s say you want to replace the first two characters of a string with 'Hello':

x = "This is a test"
puts x.sub(/^../, 'Hello')

In this case, you make a single substitution with sub. The first parameter given to sub isn’t a string but a regular expression—forward slashes are used to start and end a regular expression. Within the regular expression is ^... The ^ is an anchor, meaning the regular expression will match from the beginning of any lines within the string. The two periods each represent “any character.” In all, /^../ means “any two characters immediately after the start of a line.” Therefore, Th of "This is a test" gets replaced with Hello. Likewise, if you want to change the last two letters, you can use a different anchor:

x = "This is a test"
puts x.sub(/..$/, 'Hello')

Note: If you want to anchor to the absolute start or end of a string, you can use \A and \Z respectively,
whereas ^ and $ anchor to the starts and ends of lines.

6) Iteration with a Regular Expression

If we want to iterate through a string and have access to each section of it separately? scan is the iterator method you require:

"xyz".scan(/./) { |letter| puts letter }

prints
x
y
z

7) Basic Special Characters and Symbols Within Regular Expressions














CharacterMeaning
^Anchor for the beginning of a line
$Anchor for the end of a line
\AAnchor for the start of a string
\ZAnchor for the end of a string
.Anchor for the end of a string
\wAny letter, digit, or underscore
\WAnything that \w doesn’t match
\dAny digit
\DAnything that \D doesn’t match (non-digits)
\sWhitespace (spaces, tabs, newlines, and so on)
\SNon-whitespace (any visible character)


+ after a character in a regular expression means match one or more of that type of character.

8) Regular Expression Character and Sub-Expression Modifiers










ModifierDescription
*Match zero or more occurrences of the preceding character, and match as many as possible.
+Match one or more occurrences of the preceding character, and match as many as possible.
*?Match zero or more occurrences of the preceding character, and match as few as possible.
+?Match one or more occurrences of the preceding character, and match as few as possible.
?Match either one or none of the preceding character.
{x}Match x occurrences of the preceding character.
{x,y}Match at least x occurrences and at most y occurrences.


9) Matching

Making substitutions and extracting certain text from strings is useful, but sometimes you merely want to check whether a certain string matches against the pattern of your choice. You might want to establish quickly if a string contains any vowels:

puts "String has vowels" if "This is a test" =~ /[aeiou]/

In this example, =~ is another form of operator, a matching operator. If the string matches the regular expression following the operator, then the expression is true. You can, of course, do the opposite:

puts "String contains no digits" unless "This is a test" =~ /[0-9]/

This time you’re saying that unless the range of digits from 0 to 9 matches against the test string, tell the user that there are no digits in the string.

10) Splitting Strings into Arrays

With scan you used a block of code that accepted each set of characters and displayed them on the screen. However, if you use scan without a block of code, it returns an array of all the matching parts of the string, like so:

puts "This is a test".scan(/\w/).join(',')

Output: T,h,i,s,i,s,a,t,e,s,t

First you define a string literal, then you scan over it for alphanumeric characters (using /\w/), and finally you join the elements of the returned array together with commas.What if you don’t want to scan for particular characters, but instead want to split a string into multiple pieces? You can use the split method, and tell it to split a string into an array of strings on the periods, like so:

puts "Short sentence. Another. No more.".split(/\./).inspect

["Short sentence", " Another", " No more"]

11) Array Iteration

Iterating through arrays is simple and uses the each method. The each method goes through each element of the array and passes it as a parameter to the code block you supply.

For example:
[1, "test", 2, 3, 4].each { |element| puts element.to_s + "X" }

12) Although each iterates through elements of an array, you can also convert an array on
the fly using the collect method:

[1, 2, 3, 4].collect { |element| element * 2 }

13) Deleting Hash Elements
Deleting hash elements is easy with the delete method. All you do is pass in a key as a
parameter and the element is removed:

x = { "a" => 1, "b" => 2 }
x.delete("a")
puts x.inspect

14) Hashes Within Hashes

It’s possible to have hashes (or, indeed, any sort of object) within hashes, and even arrays within hashes, within hashes! Because everything is an object and hashes and arrays can contain any other objects, there exists the ability to create giant tree structures with hashes and arrays. Here’s a demonstration:

people = {
'fred' => {
'name' => 'Fred Elliott',
'age' => 63,
'gender' => 'male',
'favorite painters' => ['Monet', 'Constable', 'Da Vinci']
},
'janet' => {
'name' => 'Janet S Porter',
'age' => 55,
'gender' => 'female'
}
}
puts people['fred']['age']
puts people['janet']['gender']
puts people['janet'].inspect

15) Code Blocks

Example:

class VowelDemo

def each_vowel(&code_block)
%w{a e i o u}.each {
|vowel| code_block.call(vowel)
}
end

v=VowelDemo.new
v.each_vowel { |vowel| puts vowel }

end

An alternate technique is to use the yield method, which automatically detects any passed code block and passes control to it:

def each_vowel
%w{a e i o u}.each { |vowel| yield vowel }
end
each_vowel { |vowel| puts vowel }


About the Author

Peter Cooper is a highly experienced Ruby developer and trainer. He manages BigBold (www.bigbold.com), a Ruby training and development company, and has produced many commercial web sites using Ruby on Rails, the Ruby-based web framework. In addition, he created Code Snippets, one of the world’s largest public code repositories, and Congress, an online chat client utilizing Ajax and Ruby on Rails. He also created Feed Digest, a feed distribution service that was recently profiled by Business 2.0 magazine.

In addition to development work, Peter has written professionally about various development techniques and tools, producing over 100 articles. He was coeditor of WebDeveloper.com, and worked on iBoost.com and Webpedia.com.

He lives in Lincolnshire, England, with his girlfriend. In his spare time he enjoys hiking, camping, and exploring mountains.

No comments: