我编写了以下递归函数,以便解析一些设置并正确填充我的一些日志文件对象。
当我针对Code Climate运行此代码时,它告诉我(当然)不鼓励使用eval
。有没有办法可以重写这个方法,所以我不需要eval
,也不需要case
语句?没有什么可以想到的。
def parse(settings, logfile = nil)
settings.each do |key, value|
if value.is_a?(Hash)
logfile = Logmsg::LogFile.new
parse(value, logfile)
else
eval("logfile.#{key} = value")
end
end
end
有什么想法吗?
我正在尝试instance_variable_set
元编程方法,但我仍然遇到一些问题。出于某种原因,由于
Argument Error: comparison of Fixnum with String failed
我仍然想弄明白。
答案 0 :(得分:5)
由于赋值给对象的属性只是方法调用的语法糖(即obj.foo = bar
与使用参数foo=
调用obj
上的bar
方法相同),使用Object#public_send
:
logfile.public_send(:"#{key}=", value)
在较旧的代码中,您经常会看到send
而不是public_send
,但您应该使用后者,因为如果您尝试调用私有方法,则会引发错误。
答案 1 :(得分:0)
这行得通,只是有点大。
module Ev
@@num = 0
def self.b26(i)
@out = ""
while i > 0
@out = (i % 26).chr + @out
i /= 26
end
return @out
end
def self.getNames
@@num += 1
@name = "#{self.b26(@@num)}.rb"
while File.exist?(@name)
@name = "#{self.b26(@@num)}.rb"
end
return @name
end
def self.run(str)
name = self.getNames
file = File.open(name, "w+")
file.write(str)
file.close()
require "./#{name}"
File.delete(name)
end
end
Ev.run("puts 2 + 2") # 4
Ev.run("puts 'Hello World!!!'") # puts 'Hello World!!!'
for x in 0..5
Ev.run("puts #{x}")
end
# 0
# 1
# 2
# 3
# 4
# 5