我正在尝试通过使用args动态定义方法来重构代码。我尝试使用Define_method,但是它抛出一个错误,并且我不得不定义define_singleton_method。
这是我的代码,我想删除所有带有call_ *前缀的方法。
def construct_payload(id, file_name, type)
case type
when 'Radio' then call_radio(id, file_name)
when 'Pan' then call_pan(id, file_name)
end
end
def call_radio(_id, _file_name)
base(_id).merge(radio(_file_name))
end
def call_pan(_id, _file_name)
base(_id).merge(pan(_file_name))
end
def base(_id)
{
"id": _id,
}
end
def radio(file)
{
"mode": "ds",
"file": file
}
end
def pan(file)
{
"mode": "pr",
"file": file
}
end
#enter code here
是否可以动态定义call_radio
和call_pan
方法?
答案 0 :(得分:3)
case (type)
通常是一个强烈的信号,您需要创建子类,而不是拥有一个伪装成不同类的全能类。
例如:
class Radio < BaseClass
def call(id, _file_name)
# ...
end
end
class Pan < BaseClass
def call(id, _file_name)
# ...
end
end
然后,您只需实例化正确的类并调用正确的方法即可。
这是面向对象设计的原则之一,您可以在适当的地方专门化类,而不要使用非专业的类来处理许多不同的,通常是矛盾的事情。
您可以使用method_missing
或通过调用define_method
进行一些技巧,但是与在这种情况下定义子类相比,这需要大量的工作。
答案 1 :(得分:0)
我认为eval是编写更少代码的更好选择
def construct_payload(id, file_name, type)
eval("base(id).merge(#{type}(file_name))")
end
def base(_id)
{
"id": _id,
}
end
def radio(file)
{
"mode": "ds",
"file": file
}
end
def pan(file)
{
"mode": "pr",
"file": file
}
end