We tenderized the wrong method! Object#try already had the yield option, just...

We tenderized the wrong method! Object#try already had the yield option, just needed some tenderloving instance_eval to fit the bill
上级 39691ba2
* Added yield to Object#presence, so you can do this:
* Added instance_eval version to Object#try, so you can do this:
project.account.owner.presence { name.first } || 'Nobody'
person.try { name.first }
instead of calling twice (which may incur double SQL calls):
instead of:
project.account.owner ? project.account.owner.name.first || 'Nobody'
or assigning to local variable:
owner = project.account.owner
owner ? owner.name.first || 'Nobody'
person.try { |person| person.name.first }
*DHH*
......
......@@ -39,21 +39,9 @@ def present?
#
# region = params[:state].presence || params[:country].presence || 'US'
#
# You can also use this with a block that will be yielded if the object is present
# and the result of that block will then be returned. The block itself is run against
# the instance you're running #presence on (using instance_eval)
#
# project.account.owner.presence { name.first } || 'Nobody'
#
# @return [Object]
def presence(&block)
if present?
if block_given?
instance_eval(&block)
else
self
end
end
def presence
self if present?
end
end
......
......@@ -33,6 +33,11 @@ class Object
# ...
# end
#
# You can also call try with a block without accepting an argument, and the block
# will be instance_eval'ed instead:
#
# @person.try { upcase.truncate(50) }
#
# Please also note that +try+ is defined on +Object+, therefore it won't work
# with instances of classes that do not have +Object+ among their ancestors,
# like direct subclasses of +BasicObject+. For example, using +try+ with
......@@ -40,7 +45,11 @@ class Object
# delegator itself.
def try(*a, &b)
if a.empty? && block_given?
yield self
if b.arity.zero?
instance_eval(&b)
else
yield self
end
else
public_send(*a, &b) if respond_to?(a.first)
end
......
......@@ -28,14 +28,4 @@ def test_present
BLANK.each { |v| assert_equal false, v.present?, "#{v.inspect} should not be present" }
NOT.each { |v| assert_equal true, v.present?, "#{v.inspect} should be present" }
end
def test_presence
BLANK.each { |v| assert_equal nil, v.presence, "#{v.inspect}.presence should return nil" }
NOT.each { |v| assert_equal v, v.presence, "#{v.inspect}.presence should return self" }
end
def test_presence_with_a_block
assert_equal "THIS WAS TENDERLOVE'S IDEA", "this was tenderlove's idea".presence { upcase } || "Nobody"
assert_equal "Nobody", nil.presence { upcase } || "Nobody"
end
end
......@@ -65,6 +65,10 @@ def test_try_only_block_nil
assert_equal false, ran
end
def test_try_with_instance_eval_block
assert_equal @string.reverse, @string.try { reverse }
end
def test_try_with_private_method_bang
klass = Class.new do
private
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册