有时我们最终会编写几个方法,如下所示:
module XyzGateway
module Defaults
def pull_sample asynch=true
'N/A'
end
def is_pull_available?
false
end
def is_push_available?
true
end
def connect params
logger.debug "Invalid gateway(#{self.id}), could not resolve its type. #{ap self}"
end
def gateway_init
end
def disconnect
end
end
end
我只是在寻找一种方法来避免在这种情况下使用这些def
和end
关键字,有什么出路吗?在我上面的情况下,这些是默认行为,如果我能避免这些def
,我会很高兴end
。
编辑:是的,实际上我确实有一个模块XyzGateway::D所有这些故障。
您无法避免它们,除非使用 define_method
:
define_method :is_pull_available? { false }
如果你的目标只是缩短你的代码,你可以把整个方法放在一行上,这对于极短的方法来说并不是那么糟糕(这里的第四种方法可能有点太长了,像这样压缩它会损害可读性,IMO):
def pull_sample(asynch = true); 'N/A'; end
def is_pull_available?; false; end
def is_push_available?; true; end
def connect params; logger.debug "Invalid gateway(#{self.id}), could not resolve its type. #{ap self}"; end
def gateway_init; end
def disconnect; end
对于静态方法,您可以定义哈希并使用它来定义方法:
methods_to_define = { 'pull_sample' => 'N/A', 'is_pull_available?' => false,
'is_push_available?' => true, 'gateway_init' => nil, 'disconnect' => nil }
methods_to_define.each_pair do |key, value|
define_method(key) { value }
end
我有时也会遇到这个问题。它甚至会让我觉得我对 Ruby 来说太聪明了。我知道事实并非如此。实际上,我认为我只是以一种不理想的方式使用语言。
当我有一系列单行方法时,我发现这是几乎任何面向对象重构的最终结论,我想我也锁定了设计。如果代码已经围绕问题成熟,这可能是一件好事,但过早地做可能是一件坏事。出于这个原因,我尽量让方法更加随意,并在骨头上放一些肉。
我还发现,当我有一系列单行方法时,我可能越来越接近实现 lisp 之美的一个方面。但我认为,Ruby simple似乎不是这样做的合适地方。
所以相反,我宁愿成为Ruby的样子。嗯,这是什么意思?
我见过很多人这样做。
def is_pull_available?; false end
知道省略第二个;
是至少熟悉 Ruby 语法这一方面的人的标志。
这既快速又容易做到,但仍然有点嘶吼。
那么 Ruby programmar 要做什么呢?也许有一点额外的空闲时间?好吧,也许他们可以创建一个DSL。无论如何,这就是他们到目前为止所做的一切,不妨更优雅地呈现它。
所以也许我们转向
def is_pull_available?
false
end
到
pull_available false
要实现这一目标,您真正需要做的就是...
def self.pull_available(value)
define_method(:is_pull_available?) { value }
end
要么把它扔到基类中,要么从模块中混合进来。
我认为这确实是当您真正想要锁定域逻辑并强调它时要保留的步骤。你越打磨它,当它改变时,你就越会感觉不好。
Ruby 中的元编程可能是一本很棒的书,如果你对这类东西感兴趣的话。
这个怎么样?
class Module
def simple_method meth, value
define_method(meth){value}
end
end
class A
simple_method :is_pull_available?, false
end
或
class Module
def simple_method hash
hash.each do |key, value|
define_method(key){value}
end
end
end
class A
# Ruby 1.9 only
simple_method is_pull_available?: false
end