我有以下示例ruby代码:
def example_method(obj)
ExampleClass.new(color1: @theme.try(obj['color1'].to_sym))
end
哪个应该将obj['color1']
作为符号或nil传递给该类。
但如果未通过color1
,我会收到错误:NoMethodError: undefined method 'to_sym' for nil:NilClass
。
try方法不应该处理异常吗?
更新:基于评论...我通过三元组解决了这个问题:
ExampleClass.new(color1: obj['color1'].present? ? @brand_theme.try(obj['color1'].try(:to_sym)) : nil)
答案 0 :(得分:3)
您可以编写辅助方法:
def theme_color(name)
return unless name
return unless @theme.respond_to?(name)
@theme.public_send(name)
end
def example_method(obj)
ExampleClass.new(color1: theme_color(obj['color1']))
end
如果参数为theme_color
, nil
会返回nil
,即obj['color1']
。如果nil
未响应给定方法,它也会返回theme
。否则,它将调用name
指定的方法。
请注意,respond_to?
和public_send
接受字符串或符号,因此不需要to_sym
。
您还可以将辅助方法定义为@theme
类的实例方法:
class Theme
def color(name)
return unless name
return unless respond_to?(name)
public_send(name)
end
def red
'FF0000'
end
end
@theme = Theme.new
@theme.red #=> "FF0000"
@theme.color(:red) #=> "FF0000"
@theme.color('red') #=> "FF0000"
@theme.color('green') #=> nil
@theme.color(nil) #=> nil
通过以下方式调用它:
def example_method(obj)
ExampleClass.new(color1: @theme.color(obj['color1']))
end
请注意,这些方法(使用public_send
或try
)允许您在@theme
对象上调用任意方法。将颜色保留在散列中可能更安全。
答案 1 :(得分:2)
在try
对象上调用@theme
。抛出nil错误是因为obj['color1']
返回nil,然后在to_sym
上调用nil
。
您必须将代码更改为
ExampleClass.new(color1: @theme.try(obj['color1'].try(:to_sym) || ''))
抓住那个。
然后你必须美化代码。
美化效果如何取决于用例,所以我只能提供一些通用指针。一种方法是将默认值设为avoid having to deal with the null object
不是传递nil,而是简单地返回一个默认值:
color_key = obj.fetch('color') { 'default_color' }.to_sym
ExampleClass.new(color1: @theme.send(color_key)))
这使用了fetch method,可以返回默认值。这样,您将始终定义一个值。
答案 2 :(得分:2)
来自评论:
在此示例中,
obj['color1']
将为零。所以我们通过nil尝试。
是的,这是一个错误。你无法调用没有名字的方法。 从技术上讲,你可以通过.try(obj['color'].to_s)
来避免错误,但这是错误的。
如果不存在,我会明确检查存在并提前保释。
def example_method(obj)
return unless obj['color1'].present?
ExampleClass.new(color1: @theme.try(obj['color1']))
end