1

時々、次のようないくつかのメソッドを書くことになります:

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::Defaults があります。

4

4 に答える 4

4

を使用しない限り、それらを回避することはできませんdefine_method

define_method :is_pull_available? { false }

ただし、コードを短くするだけが目的の場合は、メソッド全体を 1 行に入れることができます。これは、非常に短いメソッドの場合はそれほど悪くありません (ここでの 4 番目のメソッドはおそらく少し長すぎて、このように要約すると読みやすさが損なわれます。 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
于 2012-08-17T04:14:19.303 に答える
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
于 2012-08-17T04:22:30.187 に答える
2

私も時々この問題を抱えています。それどころか、自分が Ruby に対して賢くなりすぎているような気がすることさえあります。私はそうではないことを知っています。実際には、言語を理想的でない方法で使用しているだけだと思います。

ほぼすべてのオブジェクト指向リファクタリングの最終的な結論である一連の 1 行のメソッドがある場合、私は設計にもロックされていると考えます。これは、コードが問題を回避して成熟している場合はおそらく良いことですが、時期尚早に行うのはおそらく悪いことです。そのため、私はメソッドをもう少し意地悪で骨に肉をつけたままにしようとしています.

また、一連の 1 行のメソッドを使用すると、Lisp の美しさの 1 つの側面を実現することにおそらく近づいていることもわかります。しかし、Ruby simple はそれを行うのに適切な場所ではないように思えます。

代わりに、私は Ruby のようになりたいと思います。さて、それはどういう意味ですか?

多くの人がこれをしているのを見てきました。

def is_pull_available?; false end

2 番目を省略できることを知って;いるということは、Ruby 文法のその側面に少なくとも精通していることを示しています。

これはすばやく簡単に実行できますが、それでもちょっと面倒です。

では、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は、この種の事柄に興味がある場合に読むのに最適な本です。

于 2012-08-17T04:48:54.903 に答える
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
于 2012-08-17T19:48:05.560 に答える