samedi 26 mai 2012

Introduction to Ruby and Rails

Ruby is an Interpreted and Object-oriented language where Everything is an object and Every operation is a method call on some object.
Ruby is Dynamically typed, i.e. objects have types, but variables don’t. Dynamic means add, modify code at runtime (metaprogramming), ask objects about themselves (reflection), and in a sense all programming is metaprogramming.


Ruby is ...


an Interpreted and Object-oriented language where Everything is an object and Every operation is a method call on some object.
Ruby is Dynamically typed, i.e. objects have types, but variables don’t. Dynamic means add, modify code at runtime (metaprogramming), ask objects about themselves (reflection), and in a sense all programming is metaprogramming.


Naming conventions

Class names use UpperCamelCase, for instance class FriendFinder ...  end
Methods and variables use snake_case, for def learn_conventions  ...  enddef faculty_member?  ...  enddef charge_credit_card!  ...  end.
Constants (scoped) & $GLOBALS (not scoped) are must be in upper case: TEST_MODE = true, $TEST_MODE = true.
Symbols are immutable string whose value is itself, for example:

  • favorite_framework = :rails
  • :rails.to_s == "rails"
  • "rails".to_sym == :rails
  • :rails == "rails"  # => false

Variables, Arrays, Hashes

In Ruby, there are no variable declarations, although local variables must be assigned before use and instance and class variables are equal to nil until been assigned. 
It is OK to write:  x = 3; x = 'foo' but it's wrong to write  Integer x=3.
In Ruby, Array and Hash elements can be anyting, including other arrays/hashes, and don't all have to be same type.  As in python and perl, hashes are the swiss army chainsaw of building data structures.
Examples of Array:  x = [1,'two',:three]; x[1] == 'two' ; x.length==3
Examples of Hash:  w = {'a'=>1, :b=>[2, 3]}, w[:b][0] == 2 , w.keys == ['a', :b]

Methods

Everything (except fixnums) is pass-by-reference. Example of methods: 
def foo(x,y)    
  return [x,y+1]
end

def foo(x,y=0)  # y is optional, 0 if omitted
  [x,y+1]       # last exp returned as result
end

def foo(x,y=0) ; [x,y+1] ; end

Methods can be called with:  a,b = foo(x,y) or a,b = foo(x) when optional arg used.

Basic Constructs

In Ruby, statements end with ';' or newline, but can span line if parsing is unambiguous
It is OK to write (as unless cannot end a statement):
raise("Boom!") unless
        (ship_stable)   
But it is wrong to write:
raise("Boom!")
        unless (ship_stable)
Basic Comparisons & Booleans (are just like in all modern programming languges): == != < >  =~  !~  true   false nil  
The usual control flow constructs are:

Strings & Regular Expressions

You should try rubular.com for any regex needs. An example of regex: "string", %Q{string}, 'string', %q{string}
To match a=41 ; the corresponding regex is #{a+1}
Match a string against a regexp (just like with pyhon):
  • "fox@berkeley.EDU" =~ /(.*)@(.*)\.edu$/i
  • /(.*)@(.*)\.edu$/i =~ "fox@berkeley.EDU"
If no match, returned value is false, in case of  match, value is non-false, and $1...$n capture parenthesized groups ($1 == 'fox', $2 == 'berkeley')
/(.*)$/i  or  %r{(.*)$}i   or  Regexp.new('(.*)$', Regexp::IGNORECASE)

Everything is an object; (almost) everything is a method call

Even lowly integers and nil are true objects, and we can write 57.methods57.heinz_varieties, and nil.respond_to?(:to_s) 
Rewrite each of these as calls to send for example:  my_str.length  =>  my_str.send(:length)
  • 1 + 2 is equivalent to 1.send(:+, 2) 
  • my_array[4]  is equivalent to my_array.send(:[], 4)
  • my_array[3] = "foo"   is equivalent to my_array.send(:[]=, 3,"foo")
  • if (x == 3)  ....   is equivalent to if (x.send(:==, 3)) ...
  • my_func(z) is equivalent to self.send(:my_func, z)
In particular, things like “implicit conversion” on comparison is not in the type system, but in the instance methods.

a.b means: call method b on object a, i.e. a is the receiver to which you send the method call, assuming a will respond to that method. It does not mean:  b is an instance variable of a, and does not mean also:  a is some kind of data structure that has b as a member

Understanding this distinction will save you from much grief and confusion.



Aucun commentaire:

Enregistrer un commentaire