用Ruby写一系列单行方法的更简洁的方法?

dojqjjoe  于 12个月前  发布在  Ruby
关注(0)|答案(5)|浏览(83)

有时我们会写几个方法,比如:

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::socket用于所有这些。

z9gpfhce

z9gpfhce1#

您无法避免它们,除非使用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
uoifb46i

uoifb46i2#

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

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
pokxtpni

pokxtpni3#

我有时也有这个问题。它甚至让我觉得我对露比来说太聪明了。我知道事实并非如此。事实上,我认为我只是在以一种不理想的方式使用语言。
当我有一系列单行方法时,我发现这是任何面向对象重构的最终结论,我想我也锁定了设计。如果代码已经围绕问题成熟,这可能是一件好事,但过早地做可能是一件坏事。出于这个原因,我试着让这些方法更随意一点,并在骨头上加一些肉。
我还发现,当我有一系列单行方法时,我可能离实现lisp之美的一个方面越来越近了。但我认为,Ruby simple似乎不适合这样做。
所以,我更喜欢像鲁比那样。那是什么意思
我见过很多人这么做。

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可能是一本很棒的书,如果你对这类东西感兴趣的话。

qybjjes1

qybjjes14#

Ruby ~> 3.0中的另一个选项

def pull_sample(*) = 'N/A'

    def is_pull_available? = false

    def is_push_available? = true

    def connect(*) = logger.debug "Invalid gateway(#{self.id}), could not resolve its type. #{ap self}"

    def gateway_init = nil

    def disconnect = nil
elcex8rz

elcex8rz5#

这个怎么样?

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

相关问题