在Ruby中编写一系列单行方法的更简洁方法?

时间:2012-08-17 03:36:42

标签: ruby

有时我们最终会编写几种类似的方法:

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

在这种情况下,我只想找到一种避免这些defend关键字的方法,有什么办法吗?在上面的例子中,这些都是默认行为,如果我能避免这些defend,我会很高兴。

编辑:是的,实际上我确实有一个模块XyzGateway :: Defaults for all。

4 个答案:

答案 0 :(得分:4)

除了使用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

答案 1 :(得分:2)

对于静态方法,您可以定义哈希并使用它来定义方法:

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

答案 2 :(得分:2)

我有时也有这个问题。它甚至可以让我觉得我对Ruby太聪明了。我知道事实并非如此。实际上,我认为我只是以非理想的方式使用该语言。

当我有一系列一行方法时,我发现它几乎是任何面向对象的重构的终极结论,我想我也已经锁定了设计。如果代码已经在问题周围成熟,这可能是一件好事,但可能是过早做坏事。出于这个原因,我试图让这些方法更加无聊,并且在骨头上放一些肉。

我还发现,当我有一系列一行方法时,我可能会越来越接近实现lisp之美的一个方面。但是,我认为Ruby简单似乎不是正确的做法。

相反,我宁愿像Ruby一样。那是什么意思呢?

我见过很多人这样做。

def is_pull_available?; false end

知道离开第二个;是一个至少熟悉Ruby语法方面的人的标志。

这很容易做到,但还是有点yuk。

那么Ruby程序员要做什么?也许还有一点额外的空闲时间?好吧,也许他们可以创建一个DSL。无论如何,这就是他们到目前为止所做的一切,不妨以更优雅的方式呈现它。

所以也许我们转向

def is_pull_available?
  false
end

进入

pull_available false

实现这一目标真正需要做的就是......

def self.pull_available(value)
  define_method(:is_pull_available?) { value }
end

要么将其抛入基类,要么将其与模块混合。

我认为当你真正想要锁定域逻辑并强调它时,这是一个你想要保留的步骤。你弄得越多,你在变化时就会感觉不好。

如果你对这种东西感兴趣,那么

Metaprogramming in Ruby可能是一本很好的书。

答案 3 :(得分:0)

这个怎么样?

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