Friday, October 14, 2011

Things to remember for ruby

The Ruby parser is complex and relatively forgiving. It tries to make sense out of what it finds instead of forcing the programmer into slavishly following a set of rules. However, this behavior may take some getting used to. Here is a list of things to know about Ruby syntax:
  • Parentheses are usually optional with a method call. These calls are all valid:
    foobar
    foobar()
    foobar(a,b,c)
    foobar a, b, c
  • Given that parentheses are optional, what does x y z mean, if anything? As it turns out, this means, "Invoke method y, passing z as a parameter, and pass the result as a parameter to method x." In short, the statement x(y(z)) means the same thing.
  • Let's try to pass a hash to a method:
    my_method {a=>1, b=>2}
    This results in a syntax error, because the left brace is seen as the start of a block. In this instance, parentheses are necessary:
    my_method({a=>1, b=>2})
  • Now let's suppose that the hash is the only parameter (or the last parameter) to a method. Ruby forgivingly lets us omit the braces:
    my_method(a=>1, b=>2)
    Some people might think that this looks like a method invocation with named parameters. Really it isn't, though it could be used as such.
  • There are other cases in which blank spaces are semi-significant. For example, these four expressions may all seem to mean the same:
    x = y + z
    x = y+z
    x = y+ z
    x = y +z
    And in fact, the first three do mean the same. However, in the fourth case, the parser thinks that y is a method call and +z is a parameter passed to it! It will then give an error message for that line if there is no method named y. The moral is to use blank spaces in a reasonable way.
  • Similarly, x = y*z is a multiplication of y and z, whereas x = y *z is an invocation of method y, passing an expansion of array z as a parameter.
  • In constructing identifiers, the underscore is considered to be lowercase. Thus an identifier may start with an underscore, but it will not be a constant even if the next letter is uppercase.
  • In linear nested-if statements, the keyword elsif is used rather than else if or elif as in some languages.
  • Keywords in Ruby are not really reserved words. When a method is called with a receiver (or in other cases where there is no ambiguity), a keyword may be used as a method name. Do this with caution, remembering that programs should be readable by humans.
  • The keyword then is optional (in if and case statements). Those who want to use it for readability may do so. The same is true for do in while and until loops.
  • The question mark and exclamation point are not really part of the identifier that they modify but should be considered suffixes. Thus we see that although, for example, chop and chop! are considered different identifiers, it is not permissible to use these characters in any other position in the word. Likewise, we use defined? in Ruby, but defined is the keyword.
  • Inside a string, the pound sign (#) is used to signal expressions to be evaluated. That means that in some circumstances, when a pound sign occurs in a string, it has to be escaped with a backslash, but this is only when the next character is a { (left brace), $ (dollar sign), or @ (at sign).
  • Because of the fact that the question mark may be appended to an identifier, care should be taken with spacing around the ternary operator. For example, suppose we have a variable my_flag, which stores either TRue or false. Then the first line of code shown here will be correct, but the second will give a syntax error:
    x = my_flag ? 23 : 45   # OK
    x = my_flag? 23 : 45 # Syntax error
  • The ending marker =end for embedded documentation should not be considered a token. It marks the entire line and thus any characters on the rest of that line are not considered part of the program text but belong to the embedded document.
  • There are no arbitrary blocks in Ruby; that is, you can't start a block whenever you feel like it as in C. Blocks are allowed only where they are neededfor example, attached to an iterator. The exception is the begin-end block, which can be used basically anywhere.
  • Remember that the keywords BEGIN and END are completely different from the begin and end keywords.
  • When strings bump together (static concatenation), the concatenation is of a lower precedence than a method call. For example:
    str = "First " 'second'.center(20)     # Examples 1 and 2
    str = "First " + 'second'.center(20) # are the same.
    str = "First second".center(20) # Examples 3 and 4
    str = ("First " + 'second').center(20) # are the same.
  • Ruby has several pseudovariables, which look like local variables but really serve specialized purposes. These are self, nil, true, false, __FILE__, and __LINE__.

No comments:

Post a Comment