我正在阅读另一个问题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
我不太明白第二部分的作用 - 有人可以解释一下吗?
答案 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和其他语言中使用它们。
在这种情况下,您不会从将各自的布尔属性存储到各个位中获得任何结果,我建议您不要实际使用此代码。最好为每个属性使用不同的实例变量,并使用true
或false
值。