Today i have read first 3 chapters from the book and I wanted to share few important quotations i found from the first 3 chapters.
Tomorrow i will continue updating this ruby series with next 3 chapters.
1) I have downloaded ruby 1.8.6 version from the ruby offficial site.
2) Ruby is a dynamic programming language with a complex but expressive grammar and a core class library with a rich and powerful API. Ruby draws inspiration from Lisp, Smalltalk, and Perl, but uses a grammar that is easy for C and Java™ programmers to learn. Ruby is a pure object-oriented language, but it is also suitable for procedural and functional programming styles. It includes powerful metaprogramming capabilities and can be used to create domain-specific languages or DSLs.
3) This article describes clearly how to install ruby eclipse plugin and also tries to highlight ruby benefits.
Few points from the article.
a) Why would any self-respecting Java developer care about Ruby? Ruby is a general-purpose scripting language created 10 years ago in Japan. Contrary to popular belief, it is a pure object-oriented language. Unlike Java technology, Ruby has no scalars, so everything, including integers, are first-class objects. Ruby's syntax borrows heavily from Smalltalk, Python, and Ada. Like the Java programming language, Ruby is a single inheritance language, but it offers some advanced features that Java technology does not, such as closures (think anonymous inner classes on steroids) and mix-ins (similar to interfaces, but less tightly bound to the class). Ruby is also highly portable, running on all major operating systems.
b) Ruby on Rails is a framework for creating Web applications backed by databases that shows this elegance. Rake, Ruby's version of Make and Ant rolled into one, is another example of this powerful use of the language.
4) Every value is an object, even simple numeric literals and the values true, false, and nil (nil is a special value that indicates the absence of value; it is Ruby's version of null).
5) Comments begin with # in Ruby.
6) In many languages, function and method invocations require parentheses, but there are no parentheses in any of the code above. In Ruby, parentheses are usually optional and they are commonly omitted, especially when the method being invoked takes no arguments. The fact that the parentheses are omitted in the method invocations here makes them look like references to named fields or named variables of the object. This is intentional, but the fact is, Ruby is very strict about encapsulation of its objects; there is no access to the internal state of an object from outside the object.
7) The fact that we can invoke methods on integers isn't just an esoteric aspect of Ruby. It is actually something that Ruby programmers do with some frequency:
3.times { print "Ruby! " } # Prints "Ruby! Ruby! Ruby! "
1.upto(9) {|x| print x } # Prints "123456789"
times and upto are methods implemented by integer objects. They are a special kind of method known as an iterator, and they behave like loops. The code within curly braces—known as a block—is associated with the method invocation and serves as the body of the loop. The use of iterators and blocks is another notable feature of Ruby.
8) Integers are not the only values that have iterator methods. Arrays (and similar "enumerable" objects) define an iterator named each, which invokes the associated block once for each element in the array. Each invocation of the block is passed a single element from the array:
a = [3, 2, 1] # This is an array literal
a[3] = a[2] - 1 # Use square brackets to query and set array elements
a.each do |elt| # each is an iterator. The block has a parameter elt
print elt+1 # Prints "4321"
end # This block was delimited with do/end instead of {}
9) Hashes, like arrays, are a fundamental data structure in Ruby. As their name implies, they are based on the hashtable data structure and serve to map arbitrary key objects to value objects. (To put this another way, we can say that a hash associates arbitrary value objects with key objects.) Hashes use square brackets, like arrays do, to query and set values in the hash. Instead of using an integer index, they expect key objects within the square brackets. Like the Array class, the Hash class also defines an each iterator method. This method invokes the associated block of code once for each key/value pair in the hash, and (this is where it differs from Array) passes both the key and the value as parameters to the block:
h = { # A hash that maps number names to digits
:one => 1, # The "arrows" show mappings: key=>value
:two => 2 # The colons indicate Symbol literals
}
h[:one] # => 1. Access a value by key
h[:three] = 3 # Add a new key/value pair to the hash
h.each do |key,value| # Iterate through the key/value pairs
print "#{value}:#{key}; " # Note variables substituted into string
end # Prints "1:one; 2:two; 3:three; "
10) Double-quoted strings can include arbitrary Ruby expressions delimited by #{ and }. The value of the expression within these delimiters is converted to a string (by calling its to_s method, which is supported by all objects). The resulting string is then used to replace the expression text and its delimiters in the string literal. This substitution of expression values into strings is usually called string interpolation.
print "#{value}:#{key}; " # Note variables substituted into string
11) Expressions and Operators in Ruby
a) Ruby's syntax is expression-oriented. Control structures such as if that would be called statements in other languages are actually expressions in Ruby. They have values like other simpler expressions do, and we can write code like this:
minimum = if x < y then x else y end
b) Although all "statements" in Ruby are actually expressions, they do not all return meaningful values. while loops and method definitions, for example, are expressions that normally return the value nil.
c) One of the most powerful operators to override is []. The Array and Hash classes use this operator to access array elements by index and hash values by key. But you can define [] in your classes for any purpose you want. You can even define it as a method that expects multiple arguments, comma-separated between the square brackets. (The Array class accepts an index and a length between the square brackets to indicate a subarray or "slice" of the array.) And if you want to allow square brackets to be used on the lefthand side of an assignment expression, you can define the corresponding []= operator. The value on the righthand side of the assignment will be passed as the final argument to the method that implements this operator.
d) Methods
Methods are defined with the def keyword. The return value of a method is the value of the last expression evaluated in its body:
def square(x) # Define a method named square with one parameter x
x*x # Return x squared
end # End of the method
When a method, like the one above, is defined outside of a class or a module, it is effectively a global function rather than a method to be invoked on an object. (Technically, however, a method like this becomes a private method of the Object class.) Methods can also be defined on individual objects by prefixing the name of the method with the object on which it is defined. Methods like these are known as singletonmethods, and they are how Ruby defines class methods:
def Math.square(x) # Define a class method of the Math module
x*x
end
The Math module is part of the core Ruby library, and this code adds a new method to it. This is a key feature of Ruby—classes and modules are "open" and can be modified and extended at runtime.
Method parameters may have default values specified, and methods may accept arbitrary numbers of arguments.
e) In addition to these punctuation characters at the end of method names, we'll notice punctuation characters at the start of Ruby variable names: global variables are prefixed with $, instance variables are prefixed with @, and class variables are prefixed with @@. These prefixes can take a little getting used to, but after a while you may come to appreciate the fact that the prefix tells you the scope of the variable. The prefixes are required in order to disambiguate Ruby's very flexible grammar. One way to think of variable prefixes is that they are one price we pay for being able to omit parentheses around method invocations.
12) Regexp and Range
A Regexp (regular expression) object describes a textual pattern and has methods for determining whether a given string matches that pattern or not. And a Range represents the values (usually integers) between two endpoints. Regular expressions and ranges have a literal syntax in Ruby:
Regexp and Range objects define the normal == operator for testing equality. In addition, they also define the === operator for testing matching and membership. Ruby's case statement (like the switch statement of C or Java) matches its expression against each of the possible cases using ===, so this operator is often called the case equality operator. It leads to conditional tests like these:
13) It is common for methods to have multiple names in Ruby
Example
alias size length # size is now a synonym for length
14) Ruby's strings are mutable, which may be surprising to Java programmers in particular. The []= operator allows you to alter the characters of a string or to insert, delete, and replace substrings. The << operator allows you to append to a string, and the String class defines various other methods that alter strings in place. Because strings are mutable, string literals in a program are not unique objects. If you include a string literal within a loop, it evaluates to a new object on each iteration of the loop. Call the freeze method on a string (or on any object) to prevent any future modifications to that object.
14) Chapter 2. The Structure and Execution of Ruby Programs
a) Punctuation in identifiers
Punctuation characters may appear at the start and end of Ruby identifiers. They have the following meanings:
| Punctuation character | Description |
| $ | Global variables are prefixed with a dollar sign. Following Perl's example, Ruby defines a number of global variables that include other punctuation characters, such as $_ and $-K. |
| @ | Instance variables are prefixed with a single at sign, and class variables are prefixed with two at signs. |
| ? | As a helpful convention, methods that return Boolean values often have names that end with a question mark. |
| ! | Method names may end with an exclamation point to indicate that they should be used cautiously. This naming convention is often to distinguish mutator methods that alter the object on which they are invoked from variants that return a modified copy of the original object. |
| = | Methods whose names end with an equals sign can be invoked by placing the method name, without the equals sign, on the left side of an assignment operator. |
Here are some example identifiers that contain leading or trailing punctuation characters:
$files # A global variable
@data # An instance variable
@@counter # A class variable
empty? # A Boolean-valued method or predicate
sort! # An in-place alternative to the regular sort method
timeout= # A method invoked by assignment
b) Block Structure in Ruby
Ruby programs have a block structure. Module, class, and method definitions, and most of Ruby's statements, include blocks of nested code. These blocks are delimited by keywords or punctuation and, by convention, are indented two spaces relative to the delimiters. There are two kinds of blocks in Ruby programs. One kind is formally called a "block." These blocks are the chunks of code associated with or passed to iterator methods:
3.times { print "Ruby! " }
In this code, the curly braces and the code inside them are the block associated with the iterator method invocation 3.times. Formal blocks of this kind may be delimited with curly braces, or they may be delimited with the keywords do and end:
1.upto(10) do |x|
print x
end
15) Chapter 3: Datatypes and Objects
a) Ruby also borrows the ** operator from Fortran for exponentiation. Exponents need not be integers:
x**4 # This is the same thing as x*x*x*x
x**-1 # The same thing as 1/x
x**(1/3.0) # The cube root of x
x**(1/4) # Oops! Integer division means this is x**0, which is always 1
x**(1.0/4.0) # This is the fourth-root of x
b) String Operators
Java programmers should note that the + operator does not convert its righthand operand to a string; you must do that yourself:
"Hello planet #" + planet_number.to_s # to_s converts to a string
If to_s method is not used then we will get "can't convert Fixnum into String (TypeError)" error.
c) The << operator appends its second operand to its first, and should be familiar to C++ programmers. This operator is very different from +; it alters the lefthand operand rather than creating and returning a new object:
greeting = "Hello"
greeting << " " << "World"
puts greeting # Outputs "Hello World"
d) Accessing Characters and Substrings
To alter individual characters of a string, simply use brackets on the lefthand side of an assignment expression. In Ruby 1.8, the righthand side may be an ASCII character code or a string. In Ruby 1.9, the righthand side must be a string. You can use character literals in either version of the language:
s="Hello"
s[0] = ?H # Replace first character with a capital H
s[-1] = ?O # Replace last character with a capital O
s[s.length] = ?! # ERROR! Can't assign beyond the end of the string
The righthand side of an assignment statement like this need not be a character code: it may be any string, including a multicharacter string or the empty string. Again, this works in both Ruby 1.8 and Ruby 1.9:
s = "hello" # Begin with a greeting
s[-1] = "" # Delete the last character; s is now "hell"
s[-1] = "p!" # Change new last character and add one; s is now "help!"
More often than not, you want to retrieve substrings from a string rather than individual character codes. To do this, use two comma-separated operands between the square brackets. The first operand specifies an index (which may be negative), and the second specifies a length (which must be nonnegative). The result is the substring that begins at the specified index and continues for the specified number of characters:
Another way to extract, insert, delete, or replace a substring is by indexing a string with a Range object. For our purposes here, a Range is two integers separated by dots. When a Range is used to index a string, the return value is the substring whose characters fall within the Range:
s = "hello"
s[2..3] # "ll": characters 2 and 3
s[-3..-1] # "llo": negative indexes work, too
s[0..0] # "h": this Range includes one character index
s[0...0] # "": this Range is empty
s[2..1] # "": this Range is also empty
s[7..10] # nil: this Range is outside the string bounds
s[-2..-1] = "p!" # Replacement: s becomes "help!"
s[0...0] = "Please " # Insertion: s becomes "Please help!"
s[6..10] = "" # Deletion: s becomes "Please!"
It is also possible to index a string with a string. When you do this, the return value is the first substring of the target string that matches the index string, or nil, if no match is found. This form of string indexing is really only useful on the lefthand side of an assignment statement when you want to replace the matched string with some other string:
s = "hello" # Start with the word "hello"
while(s["l"]) # While the string contains the substring "l"
s["l"] = "L"; # Replace first occurrence of "l" with "L"
end # Now we have "heLLo"
e) Like strings, arrays can also be indexed with two integers that represent a starting index and a number of elements, or a Range object. In either case, the expression returns the specified subarray:
The + operator creates a new array that contains the elements of both its operands. Use << to append elements to the end of an existing array:
a = [] # Start with an empty array
a << 1 # a is [1]
a << 2 << 3 # a is [1, 2, 3]
a << [4,5,6] # a is [1, 2, 3, [4, 5, 6]]
The Array class borrows the Boolean operators | and & and uses them for union and intersection. | concatenates its arguments and then removes all duplicate elements from the result. & returns an array that holds elements that appear in both of the operand arrays. The returned array does not contain any duplicate elements:
a = [1, 1, 2, 2, 3, 3, 4]
b = [5, 5, 4, 4, 3, 3, 2]
a | b # [1, 2, 3, 4, 5]: duplicates are removed
b | a # [5, 4, 3, 2, 1]: elements are the same, but order is different
a & b # [2, 3, 4]
b & a # [4, 3, 2]
The Array class defines quite a few useful methods. The only one we'll discuss here is the each iterator, used for looping through the elements of an array:
a = ('A'..'Z').to_a # Begin with an array of letters
a.each {|x| print x } # Print the alphabet, one letter at a time
f) Hashes
A hash is a data structure that maintains a set of objects known as keys, and associates a value with each key. Hashes are also known as maps because they map keys to values. They are sometimes called associative arrays because they associate values with each of the keys, and can be thought of as arrays in which the array index can be any object instead of an integer. An example makes this clearer:
# This hash will map the names of digits to the digits themselves
numbers = Hash.new # Create a new, empty, hash object
numbers["one"] = 1 # Map the String "one" to the Fixnum 1
numbers["two"] = 2 # Note that we are using array notation here
numbers["three"] = 3
sum = numbers["one"] + numbers["two"] # Retrieve values like this
g) A Range object represents the values between a start value and an end value. Range literals are written by placing two or three dots between the start and end value. If two dots are used, then the range is inclusive and the end value is part of the range. If three dots are used, then the range is exclusive and the end value is not part of the range:
1..10 # The integers 1 through 10, including 10
1.0...10.0 # The numbers between 1.0 and 10.0, excluding 10.0 itself
h) true and false are the two Boolean values, and they represent truth and falsehood, yes and no, on and off. nil is a special value reserved to indicate the absence of value.
i) Object Lifetime
The built-in Ruby classes have literal syntaxes, and instances of these classes are created simply by including their values literally in your code. Objects of other classes need to be explicitly created, and this is most often done with a method named new:
myObject = myClass.new
new is a method of the Class class. It allocates memory to hold the new object, then it initializes the state of that newly allocated "empty" object by invoking its initialize method. The arguments to new are passed directly on to initialize. Most classes define an initialize method to perform whatever initialization is necessary for instances
Ruby objects never need to be explicitly deallocated, as they do in languages like C and C++. Ruby uses a technique called garbage collection to automatically destroy objects that are no longer needed. An object becomes a candidate for garbage collection when it is unreachable—when there are no remaining references to the object except from other unreachable objects.
There are several ways to determine the class of an object in Ruby. The simplest is simply to ask for it:
o = "test" # This is a value
o.class # Returns an object representing the String class
If you are interested in the class hierarchy of an object, you can ask any class what its superclass is:
o.class # String: o is a String object
o.class.superclass # Object: superclass of String is Object
o.class.superclass.superclass # nil: Object has no superclass
So a particularly straightforward way to check the class of an object is by direct comparison:
o.class == String # true if is o a String
The instance_of? method does the same thing and is a little more elegant:
o.instance_of? String # true if o is a String
Usually when we test the class of an object, we would also like to know if the object is an instance of any subclass of that class. To test this, use the is_a? method, or its synonym kind_of?:
x = 1 # This is the value we're working with
x.is_a? Object # true for any value of x
j) The equal? method
The equal? method is defined by Object to test whether two values refer to exactly the same object. For any two distinct objects, this method always returns false:
a = "Ruby" # One reference to one String object
b = c = "Ruby" # Two references to another String object
a.equal?(b) # false: a and b are different objects
b.equal?(c) # true: b and c refer to the same object
k) The == operator
The == operator is the most common way to test for equality. In the Object class, it is simply a synonym for equal?, and it tests whether two object references are identical. Most classes redefine this operator to allow distinct instances to be tested for equality:
a = "Ruby" # One String object
b = "Ruby" # A different String object with the same content
a.equal?(b) # false: a and b do not refer to the same object
a == b # true: but these two distinct objects have equal values
l) Equality for Java Programmers
If you are a Java programmer, you are used to using the == operator to test if two objects are the same object, and you are used to using the equals method to test whether two distinct objects have the same value. Ruby's convention is just about the opposite of Java's
m) In Ruby 1.9, the built-in classes String, Array, Hash, Regexp, and IO all define a class method named try_convert. These methods convert their argument if it defines an appropriate implicit conversion method, or they return nil otherwise. Array.try_convert(o) returns o.to_ary if o defines that method; otherwise, it returns nil. These try_convert methods are convenient if you want to write methods that allow implicit conversions on their arguments
n) Any object may be frozen by calling its freeze method. A frozen object becomes immutable—none of its internal state may be changed, and an attempt to call any of its mutator methods fails:
s = "ice" # Strings are mutable objects
s.freeze # Make this string immutable
s.frozen? # true: it has been frozen
s.upcase! # TypeError: can't modify frozen string
s[0] = "ni" # TypeError: can't modify frozen string
Freezing a class object prevents the addition of any methods to that class.
About the Authors
David Flanagan is a computer programmer who spends most of his time writing about JavaScript and Java. His books with O'Reilly include Java in a Nutshell, Java Examples in a Nutshell, Java Foundation Classes in a Nutshell, JavaScript: The Definitive Guide, and JavaScript Pocket Reference. David has a degree in computer science and engineering from the Massachusetts Institute of Technology. He lives with his wife and children in the U.S. Pacific Northwest bewteen the cities of Seattle, Washington and Vancouver, British Columbia. David has a blog at www.davidflanagan.com.
Yukihiro Matsumoto ("Matz"), the creator of Ruby, is a professional programmer who worked for the Japanese open source company, netlab.jp. Matz is also known as one of the open source evangelists in Japan. He's released several open source products, including cmail, the emacs-based mail user agent, written entirely in emacs lisp. Ruby is his first piece of software that has become known outside of Japan
No comments:
Post a Comment