Not sure any of this is recommended practise but it appears to work so I'm noting it here.
Overriding Array Methods
1 class MyArray 2 # 3 # Initialise array 4 # 5 def initialize 6 @zog = [] 7 end 8 9 # 10 # Read from array 11 # 12 def [](x) 13 return @zog[x] 14 end 15 16 # 17 # Assign to array 18 # 19 def []=(x,y) 20 @zog[x] = y 21 end 22 endToggle Line Numbers
Used thus:
1 irb(main):021:0* a = MyArray.new 2 => #<MyArray:0x30d8074 @zog=[]> 3 irb(main):024:0> a[0] = 1 4 => 1 5 irb(main):025:0> a[0] 6 => 1 7 irb(main):026:0> a[1] = 2 8 => 2 9 irb(main):027:0> a[0] 10 => 1 11 irb(main):028:0> a[1] 12 => 2 13 irb(main):029:0>Toggle Line Numbers
Interesting that ruby doesn't seem to be fussy about array indices:
irb(main):031:0* g = [] => [] irb(main):032:0> g[5] = 2 => 2 irb(main):033:0> g[2] => nil
Contrast to python:
>>> a = [] >>> a[5] = 2 Traceback (most recent call last): File "<stdin>", line 1, in <module> IndexError: list assignment index out of range
I think if I had the choice I would rather have my wrist slapped: the ruby way looks like an opportunity for obscure bugs.
Method Missing
It took me ages to work this out but it's simple. You have a class and you want to hook into calls to any undefined methods. Maybe you want to determine the method names at runtime. The hook is called 'method_missing':
1 class Klack 2 def method_missing( strName, *args) 3 print "Calling undefined method #{strName} with arguments #{args.inspect}" 4 end 5 end 6 7 irb(main):054:0> k = Klack.new 8 => #<Klack:0x309dd84> 9 irb(main):055:0> k.wibble( :wobbles, :banana) 10 Calling undefined method wibble with arguments [:wobbles, :banana]=> nilToggle Line Numbers
args appears to be a simple array holding the arguments the method was called with.
Note how useful the .inspect method is. It's equivalent to repr in python in making anything into a human readable string. Also gotta love how easy it is to insert the values of variables into strings.
UPDATE: this does seem to make for very fragile code. Just about any problem in your method_missing method can lead to a stack overflow. Or maybe it's a rails problem?
Wots the colon?
The colon thing is handy:
b = :blah
:blah is like a string constant, something like a string, easier to type but less complex in it's implementation. Have to be careful with them though:
1 irb(main):058:0> b = :blah 2 => :blah 3 irb(main):059:0> b[1] 4 NoMethodError: undefined method `[]' for :blah:Symbol 5 from (irb):59 6 irb(main):060:0> b == 'blah' 7 => false 8 irb(main):061:0> b == :blah 9 => true 10 irb(main):062:0> b.to_s == 'blah' 11 => trueToggle Line Numbers
They don't have common string functions and :blah is NOT comparable to 'blah'.
Regular Expression Gotcha
The =~ operator for testing a string against a regular expression returns the offset of the match.
irb(main):086:0> o = "poop1" =~ /poop(\d+)(=?)/ => 0
In this case the result is zero as the match starts at character offset zero. The operator would return nil if there was no match.
If you want access to the expression match object then this does the job:
irb(main):088:0> o = /poop(\d+)(=?)/.match( "poop1") => #<MatchData:0x3085748> irb(main):089:0> o[1] => "1" irb(main):090:0>
o is the expression match object where you can examine the juicy details of the match. These are also available in global varibles such as $1, $~ etc but everyone knows that using global variables is sloppy.
Zero is True
The =~ result works nicely with an if operator to detect a match because of the strangest ruby design decision: zero is true:
irb(main):095:0> if 0 irb(main):096:1> print 'true' irb(main):097:1> else irb(main):098:1* print 'false irb(main):099:1> end true=> nil
nil is false but 0 is true.
This is totally at odds with python where 0 and None are both False (with a capital F). I think even basic has 0 as false.
Processing Arrays
The collect method looks useful for writing one-liners:
irb(main):103:0> [1,2,3].collect { |x| x + 1} => [2, 3, 4]
Each item in the array is processed by the block and the results returned in a new array. To me this is more readable than the python version:
[ i + 1 for i in [1,2,3]]


The reason zero is true is that it is simply a numerica value.
One really nasty gotcha is when you do search for something that is in the first index, index 0, and a method returns it, you'd have to make sure you're not counting a find as a failure. 0 is a common number for a lot of content, why say it is the opposite?
In Ruby, methods that don't find or don't complete successfully will return nil since nothing was found. Nil = nothing. They don't return zero, they don't return false unless it's a binary operation or test, or a method asking for a yes or no.
It's pretty simple, really, and avoids a pretty easy bug to make.
Also, about freely accessing any index at will, there's less of the likelihood that you'd be using traditional for loops that would open up those errors than using the enumeration methods such as each and collect.