我在下面的红宝石中有一个def。 我可以做些什么让它变干吗?像:
[e,t,l,te,le,le].each |xxx| do
if xxx
end
这意味着为"变量"而不仅仅是" Enumerator"。
代码:
def findLogs (obj)
if e=obj['E']
e=obj['E']['pkg'] ? "@E = #{obj['E']['pkg']},":nil
else nil
end
if t=obj['T']
t=obj['T']['pkg'] ? "@T = #{obj['T']['pkg']},":nil
else nil
end
if l=obj['L']
l=obj['L']['pkg'] ? "@L = #{obj['L']['pkg']},":nil
else nil
end
if te=obj['Te']
te=obj['Te']['pkg'] ? "@Te = #{obj['Te']['pkg']},":nil
else nil
end
if le=obj['Le']
le=obj['Le']['pkg'] ? "@Le = #{obj['Le']['pkg']},":nil
else nil
end
end
答案 0 :(得分:4)
e, t, l, te, le = %w|E T L Te Le|.map do |s|
obj[s] && obj[s]['pkg'] ? "@#{s} = #{obj[s]['pkg']}," : nil
end
对于Sergio Tulentsev:
b = binding
%w|E T L Te Le|.each do |s|
b.local_variable_set(
s.downcase.to_sym,
obj[s] && obj[s]['pkg'] ? "@#{s} = #{obj[s]['pkg']}," : nil
)
end
答案 1 :(得分:2)
正如Stefan在评论中提到的,如果你不使用它们,在findLogs中定义局部变量是没有意义的。即使你定义了两次;)。
您的代码中并不清楚。如果你想通过在String中编写Ruby代码来定义实例变量,然后使用eval
:请不要!
obj = {
'E' => nil,
'T' => { 'pkg' => 't_pkg' },
'L' => { 'not_pkg' => 'x' },
'Te' => { 'pkg' => 'te_pkg' }
}
%w(E T L Te Le).each do |var_name|
instance_variable_set("@#{var_name}", obj.dig(var_name, 'pkg'))
end
p [@E, @T, @L, @Te, @Le] # => [nil, "t_pkg", nil, "te_pkg", nil]
答案 2 :(得分:1)
这看起来更像是JS函数而不是Ruby:)
很少有事情需要注意:
else nil
可以删除,因为Ruby方法默认返回nil
nil
,再次,您可以避免它find_logs
你可以避免重复,如上所述,并用以下内容替换:
def find_logs(obj)
log_type = ["E", "T", "L", "Te", "Le"].detect do |type|
obj[type] && obj[type]["pkg"]
end
"@#{log_type} = #{obj[log_type]['pkg']}," if log_type
end
现在,这不是特别漂亮,它仍然做两件不同的事情,但它可能已经足够好了,并且它删除了重复。
我不知道你正在尝试解决的问题,但正如我们在Ruby中所做的那样,最好用类来解决它,例如这样的事情(没有经过测试,所以它可能不起作用):
class LogFormatter
LOG_TYPES = ["E", "T", "L", "Te", "Le"]
def initialize(obj:)
@obj = obj
end
def format
"@#{log_type} = #{pkg}," if log_type
end
private
attr_reader :obj
def pkg
@pkg ||= obj[log_type]["pkg"]
end
def log_type
@log_type ||= LOG_TYPES.detect { |type| obj[type] && obj[type]["pkg"] }
end
end
现在,请记住,根据你想要做的事情,这可能有点矫枉过正 - 但就个人而言,我更喜欢有一个小班,而不是让这个"复杂"其他一些课程中的方法与完全无关的责任。