我有以下方法,并希望使其更具可读性:
def value_format(value)
if value.respond_to? :to_actor
value.to_actor
elsif value.respond_to? :to_subject
value.to_subject
elsif value.respond_to? :to_json
value.to_json
elsif value.respond_to? :to_hash
value.to_hash
else
value.inspect
end
end
这是我的解决方案。你觉得怎么样?
def value_format(value)
methods = [:to_actor, :to_subject, :to_json, :to_hash, :inspect]
value.send(methods.find_all { |m| m if value.respond_to? m }.first)
end
答案 0 :(得分:4)
您的解决方案看起来不错,但您也可以使用find
代替find_all
:
METHODS = [:to_actor, :to_subject, :to_json, :to_hash, :inspect]
def value_format(value)
value.send(METHODS.find { |m| value.respond_to? m })
end
使用常量的优点是每次运行value_format
时都不会创建新数组。
答案 1 :(得分:0)
似乎对您的解决方案进行了非常简单的优化:
def value_format(value)
methods = [:to_actor, :to_subject, :to_json, :to_hash]
value.send(methods.find(:inspect) { |m| value.respond_to? m })
end
答案 2 :(得分:0)
facet gem为这个问题提供了一个优雅的解决方案(我认为)。它结合了检查对象是否响应方法并实际调用该方法的两个步骤。
所以你的例子可以改写为:
require 'facets/kernel/respond'
def value_format(v)
v.respond.to_actor || v.respond.to_subject || v.respond.to_json || v.respond.to_hash || v.respond.inspect
end
请注意,此方法仅适用于可以安全地假设这些方法都不会返回nil
或false
(因为respond
会返回nil
对象没有响应,这就是允许我们将它与一堆or
s链接在一起的原因。
由于您列出的所有方法都应该返回字符串,我相信这种方法在您的示例中可以正常工作。
# Like #respond_to? but returns the result of the call
# if it does indeed respond.
#
# class RespondExample
# def f; "f"; end
# end
#
# x = RespondExample.new
# x.respond(:f) #=> "f"
# x.respond(:g) #=> nil
#
# or
#
# x.respond.f #=> "f"
# x.respond.g #=> nil