2

個人的には、長いという事実を除けば、これに反対することは何もありませんが、本当に気になるのは単語evalです。

私はJavaScriptで多くのことを行い、悪魔のようにevalに似たものから実行します。また、パラメーターが文字列であるという事実も気になりません(これも、おそらくevalであるためです)。

メソッド名の長さの問題、「メソッド名の問題」、およびパラメーターが文字列であるという問題を修正するための独自のメソッドを作成できることはわかっていますが、本当に知りたいのは、より良い、より短いものがあるかどうかです。 、より洗練された、まだネイティブな、class_evalクラス変数を抽出する方法はありますか?

補足:との存在については知って class_variable_get() class_variables()ますが、実際には魅力的に見えません。ひどく長いですね。

編集:質問をより具体的に更新しました。

ありがとう!

4

1 に答える 1

8

を使用class_variable_getしますが、必要な場合に限ります

class_variable_get それがあなたに「魅力的」ではないという事実を除いて、より良い方法です。クラス内に到達してカプセル化を破っている場合は、何か間違ったことをしていることを示すために、この追加のバリアを設けることが適切である可能性があります。

アクセスする変数のアクセサメソッドを作成します

これらがクラスであり、変数にアクセスしてもカプセル化が壊れない場合は、それらのクラスアクセサーメソッドを作成して、より簡単できれいにする必要があります。

class Foo
  def self.bar
    @@bar
  end
end
p Foo.bar

ただし、これがクラスの場合、クラス変数が必要ですか?影響を理解していない場合(以下を参照)、実際にはクラス自体のインスタンス変数が必要な場合があります。

class Foo
  class << self
    attr_accessor :bar
  end
end

Foo.bar = 42
p Foo.bar

クラス変数の動作

クラス変数は、主に名前が原因で、クラスレベルで情報を格納する正しい方法のように初心者に表示されます。また、クラスのメソッドまたはインスタンスメソッドのどちらを使用していても、同じ構文を使用して読み取りと書き込みを行うことができるため、便利です。ただし、クラス変数はクラスとそのすべてのサブクラスの間で共有されます。

たとえば、次のコードについて考えてみます。

class Rectangle
  def self.instances
    @@instances ||= []
  end
  def initialize
    (@@instances ||= []) << self
  end
end

class Square < Rectangle
  def initialize
    super
  end
end

2.times{ Rectangle.new }
p Rectangle.instances
#=> [#<Rectangle:0x25c7808>, #<Rectangle:0x25c77d8>]

Square.new
p Square.instances
#=> [#<Rectangle:0x25c7808>, #<Rectangle:0x25c77d8>, #<Square:0x25c76d0>]

わかった!長方形は正方形ではありません!同じことを行うためのより良い方法は次のとおりです。

class Rectangle
  def self.instances
    @instances ||= []
  end
  def initialize
    self.class.instances << self
  end
end

class Square < Rectangle
  def initialize
    super
  end
end

2.times{ Rectangle.new }
p Rectangle.instances
#=> [#<Rectangle:0x25c7808>, #<Rectangle:0x25c77d8>]

2.times{ Square.new }
p Square.instances
#=> [#<Square:0x25c76d0>, #<Square:0x25c76b8>]

クラス自体にインスタンス変数とアクセサメソッドを作成することにより(これはたまたまクラスのインスタンスでありClass、同様にMyClass = Class.new)、クラスのすべてのインスタンス(および部外者)は、共有されていない情報を読み書きするための共通のクリーンな場所を持ちます他のクラス間。

作成されたすべてのインスタンスを明示的に追跡すると、「未使用」インスタンスでのガベージコレクションが防止されることに注意してください。上記のようなコードを慎重に使用してください。

class_evalよりクリーンな方法で使用する

最後に、を使用する場合はclass_eval、文字列を解析して評価する必要のないブロック形式もあることに注意してください。

Foo.class_eval('@@bar') # ugh
Foo.class_eval{ @@bar } # yum
于 2011-06-02T15:30:48.087 に答える