红宝石理解枚举法

时间:2012-06-24 23:19:32

标签: ruby metaprogramming

我正在阅读另一个问题Enums in Ruby,它有以下代码段:

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 个答案:

答案 0 :(得分:2)

Enum中,方法enum_attr在类的单例上定义,并且可供所有子类使用。此方法在类定义主体的范围内,并且在FileAttributes中使用参数:readonly, 0x0001然后:hidden, 0x0002调用它。

调用enum_attr时(让我们只看第一个电话enum_attr :readonly, 0x0001),它定义了两种方法:readonly?&amp; 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的{​​{1}}变量仍然可以在生成的方法中使用enum_attr&amp; readonly?稍后从不同的范围调用它们。{/ p> 必须使用

readonly=,因为方法的名称是动态生成的(即,我们不知道方法的名称提前)。

答案 1 :(得分:1)

您正在查看一个类方法,该方法生成使用位域存储的true / false属性。你有C(或者Java)的背景吗?如果是这样,你可能熟悉位域和一般“bit twiddling”。这些主题的大多数互联网资源都与C有关;但你仍然可以在Ruby和其他语言中使用它们。

在这种情况下,您不会从将各自的布尔属性存储到各个位中获得任何结果,我建议您不要实际使用此代码。最好为每个属性使用不同的实例变量,并使用truefalse值。