The new method in Ruby 1.9 is making some people happy and creative too.
The only problem with that in my opinion is that every one is fixed about using method chaining with the name “try” with a symbol as a parameter to escape from the:
@person.name unless @person.nil?
or
@person ? @person.name : nil
and for some strange reason they think it is natural to write:
when I see the sentence above, the first thing I want to “try” is:
Ok, the last comment was not cool, but I thought it would be funny
So, what is this post about?
In Groovy there is a built’in language construct to solve this situation in a very cool way:
The method call after the “?” is only called if the previous expression was not nil.
I could not think in a way to implement any thing like that in ruby, but I think I came out with a satisfactory solution.
What do you think about flagging your method calls with “I know this can be null, but ignore it, it is a normal situation”?
No, I’m not telling you to write all this sentence in your code 
the flag I’m using now is the “_” character.
I’m monkey patching ruby like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| class NilClass
alias :old_method_missing :method_missing
def method_missing(methodname,*args)
old_method_missing methodname, *args unless methodname.to_s =~ /.*_$/
end
end
class Object
alias :old_method_missing :method_missing
def method_missing(methodname,*args)
methodname = (methodname.to_s.gsub(/(.*)_$/,'\1')).to_sym
if respond_to? methodname
send methodname,*args
else
old_method_missing methodname, *args
end
end
end |
and you can use it like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| #test classes
class Named
attr_accessor :name
def initialize(name)
@name = name
end
end
class Person < Named
attr_accessor :name, :company
def initialize(name,company=nil)
super(name)
@company = company
end
end
#Testing starts here
def run_test
puts @person.name_
puts @person.company_.name_
end
@person = Person.new('Urubatan',Named.new('The Best'))
run_test
@person = nil
run_test |
With this little method missing hack, we just put an “_” in the end of the method name we want to call and if the target object is nil the method will not be called and we will not get a NoMethodError.
Better yet, we can even pass arguments to the method we want to call
This way, we can use this solution only in situations we know it is safe.
What do you think about this?
I prefer the groovy solution, but I kine this one better than the “try” method
<updated>
Added one more link to the list in the beggining of the post (thanks coderr)
</updated>
If you enjoyed this post, make sure you subscribe to my RSS feed!