Skip to content

Instantly share code, notes, and snippets.

@makoto
Created November 4, 2010 23:48
Show Gist options
  • Select an option

  • Save makoto/663415 to your computer and use it in GitHub Desktop.

Select an option

Save makoto/663415 to your computer and use it in GitHub Desktop.
maybe{}
# NOTE: This won't work as expected in threaded environment.
class Object
def maybe(&block)
that = self
result = NilClass.class_eval do
alias_method :orig_method_missing, :method_missing
define_method :method_missing do
nil
end
result = block.call(that)
alias_method :method_missing, :orig_method_missing
result
end
end
end
require "test/unit"
class TestTryScope < Test::Unit::TestCase
def test_should_return_nil_when_nil_calls_a_method
assert_nil(nil.maybe{|a| a.foo})
end
def test_should_return_nil_when_nil_calls_chained_methods
assert_nil(nil.maybe{|a| a.map{|b| b.capitalize}.map{|b| b.downcase}})
end
def test_should_return_nil_when_an_array_with_nil_calls_chained_method
assert_equal(
['A', nil],
['a', nil].maybe do |a|
a.map(&:upcase).map(&:downcase).map(&:upcase)
end
)
end
def test_should_return_nil_when_chained_method_returns_nil
# Same as "class Object ; def nilme ; nil ; end ; end"
Object.class_eval do
define_method :nilme do
nil
end
end
assert_nil("foo".maybe{|a| a.capitalize.nilme.downcase.aa.bbb})
end
def test_should_raise_error_if_non_nil_value_calls_undefined_method
assert_raise(NoMethodError) do
['a', 'b', 'c'].maybe{|a| a.map{|b| b.capitalize}.map{|b| b.foo(1)}}
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment