The Artima Developer Community
Sponsored Link

Ruby Buzz Forum
Handling nil in method calls

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Paul Gross

Posts: 152
Nickname: pgross
Registered: Sep, 2007

Paul Gross is a software developer for ThoughtWorks.
Handling nil in method calls Posted: Feb 17, 2008 11:49 AM
Reply to this message Reply

This post originated from an RSS feed registered with Ruby Buzz by Paul Gross.
Original Post: Handling nil in method calls
Feed Title: Paul Gross's Blog - Home
Feed URL: http://feeds.feedburner.com/pgrs
Feed Description: Posts mainly about ruby on rails.
Latest Ruby Buzz Posts
Latest Ruby Buzz Posts by Paul Gross
Latest Posts From Paul Gross's Blog - Home

Advertisement

On my current project, we noticed common pattern when dealing with nil. We would often check an object to see if it was nil before calling a method on that object:


name = person ? person.name : nil

To reduce duplication, Patrick Farley and Ali Aghareza created a nil_or method which handles this. The above code becomes:


name = person.nil_or.name

The nil_or causes the expression to return nil if the target is nil. If not, the name method is called.

The code for nil_or looks like:


module ObjectExtension
  def nil_or
    return self unless self.nil?
    Class.new do
      def method_missing(sym, *args); nil; end
    end.new
  end  
end

class Object
  include ObjectExtension
end

The nil_or method returns self if self is not nil. If self is nil, it creates a new Object which eats all method calls and returns nil.

We use a fair amount of delegation on this project using forwardable, so we created a delegator which has the same effect. For example, you can replace this delegation:


class Person
  extend Forwardable
  def_delegator :@job, :title, :job_title
end

with this one:


class Person
  extend Forwardable
  def_delegator_or_nil :@job, :title, :job_title
end

This delegation is equivalent to this code:


class Person
  def job_title
    @job ? @job.title : nil
  end
end

The code for def_delegator_or_nil looks like:


module ForwardableExtension
  def def_delegator_or_nil(accessor, method, new_method = method)
    accessor = accessor.id2name if accessor.kind_of?(Integer)
    method = method.id2name if method.kind_of?(Integer)
    new_method = new_method.id2name if new_method.kind_of?(Integer)

    module_eval(<<-EOS, "(__FORWARDABLE_EXTENSION__)", 1)
      def #{new_method}(*args, &block)
        begin
          if #{accessor}.nil?
            nil
          else
            #{accessor}.__send__(:#{method}, *args,&block)
          end
        rescue Exception
          $@.delete_if{|s| /^\\(__FORWARDABLE_EXTENSION__\\):/ =~ s} unless Forwardable::debug
          Kernel::raise
        end
      end
    EOS
  end
end

module Forwardable
  include ForwardableExtension
end

Read: Handling nil in method calls

Topic: Joomla demo camp Previous Topic   Next Topic Topic: Rotating args in Haskell, partially explained

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use