Ruby: 用参数定义方法
Ruby: define method with args
我正在尝试通过使用 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
方法?
case (type)
通常是一个强烈的信号,你需要创建子classes 而不是拥有一个 omniclass 只是假装是不同的 classes。
例如:
class Radio < BaseClass
def call(id, _file_name)
# ...
end
end
class Pan < BaseClass
def call(id, _file_name)
# ...
end
end
然后您只需实例化正确的 class 并调用正确的方法。
这是面向对象设计的原则之一,您可以在适当的地方对 class 进行专门化,而不是让一个非专门化的 class 做许多不同的、通常是相互矛盾的事情。
您可以使用 method_missing
或调用 define_method
来做一些小动作,但与在这种情况下定义子 class 相比,这需要大量工作。
我认为 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
我正在尝试通过使用 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
方法?
case (type)
通常是一个强烈的信号,你需要创建子classes 而不是拥有一个 omniclass 只是假装是不同的 classes。
例如:
class Radio < BaseClass
def call(id, _file_name)
# ...
end
end
class Pan < BaseClass
def call(id, _file_name)
# ...
end
end
然后您只需实例化正确的 class 并调用正确的方法。
这是面向对象设计的原则之一,您可以在适当的地方对 class 进行专门化,而不是让一个非专门化的 class 做许多不同的、通常是相互矛盾的事情。
您可以使用 method_missing
或调用 define_method
来做一些小动作,但与在这种情况下定义子 class 相比,这需要大量工作。
我认为 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