1

私はRubyで別のSO質問列挙型を読んでいて、次のコードスニペットがありました:

class Enum

  private

  def self.enum_attr(name, num)
    name = name.to_s

    define_method(name + '?') do
      @attrs & num != 0
    end

    define_method(name + '=') do |set|
      if set
        @attrs |= num
      else
        @attrs &= ~num
      end
    end
  end

  public

  def initialize(attrs = 0)
    @attrs = attrs
  end

  def to_i
    @attrs
  end
end

私がこれを理解しているように、これはという名前のクラスメソッドを定義しenum_attrています、それは正しいですか?私が確信していないのは、メソッドdefine_method内にステートメントがあるとはどういう意味かということです。enum_attr

その後、その投稿の後半で、クラスが次のように拡張されていることが示されています

class FileAttributes < Enum
  enum_attr :readonly,       0x0001
  enum_attr :hidden,         0x0002
end

この2番目の部分が何をするのかよくわかりません-誰かが説明できますか?

4

2 に答える 2

2

ではEnum、メソッドenum_attr、、はクラスのシングルトンで定義され、すべてのサブクラスで使用できます。このメソッドは、クラス定義本体のスコープ内にありFileAttributes、引数:readonly, 0x0001、次に。で呼び出されています:hidden, 0x0002

enum_attr呼び出されると(最初の呼び出しだけを見てみましょうenum_attr :readonly, 0x0001)、2つのメソッドを定義します:readonly?readonly=(set)。この呼び出しの結果は、enum_attr機能的に次のように書き出すのと同じですFileAttributes

def readonly?
  @attrs & 0x0001 != 0
end

def readonly=(set)
  if set
    @attrs |= 0x0001
  else
    @attrs &= ~0x0001
  end
end

渡されるブロックdefine_methodはクロージャであるため、num定義されているメソッドを呼び出すと、ブロックが渡されるスコープの変数は引き続きスコープ内にあります。つまり、にnum渡された変数はenum_attr、生成されたメソッド内で、後で別のスコープから呼び出されたときに引き続き使用できreadonly?ます。readonly=

define_methodメソッドの名前は動的に生成されるため(つまり、メソッドの名前が事前にわからないため)、使用する必要があります。

于 2012-06-24T23:44:18.090 に答える
1

あなたはビットフィールドを使用して保存されるtrue/false属性を生成するクラスメソッドを見ています。C(またはおそらくJava)のバックグラウンドはありますか?もしそうなら、あなたはビットフィールドと一般的な「ビットのいじり」に精通しているかもしれません。これらのトピックに関するほとんどのインターネットリソースはCに関連しています。ただし、Rubyやその他の言語で引き続き使用できます。

この場合、ブール属性を個々のビットに格納しても何も得られないため、実際にはこのコードを使用しないことをお勧めします。trueまたは値を使用して、属性ごとに異なるインスタンス変数を使用することをお勧めしfalseます。

于 2012-06-24T23:52:59.633 に答える