ste*_*ang 16 ruby metaprogramming class-eval
我class_eval
用来编写要在当前类的上下文中执行的代码.在以下代码中,我想为属性值的更改添加计数器.
class Class
def attr_count(attr_name)
attr_name = attr_name.to_s
attr_reader attr_name # create the attribute's getter
class_eval %Q{
@count = 0
def #{attr_name}= (attr_name)
@attr_name = attr_name
@count += 1
end
def #{attr_name}
@attr_name
end
}
end
end
class Foo
attr_count :bar
end
f = Foo.new
f.bar = 1
Run Code Online (Sandbox Code Playgroud)
我的理解class_eval
是它在运行时类的上下文中计算块- 在我的例子中,在class Foo
.我希望上面的代码运行类似于:
class Foo
attr_count :bar
@count = 0
def bar= (attr_name)
@attr_name = attr_name
@count += 1
end
def bar
@attr_name
end
end
Run Code Online (Sandbox Code Playgroud)
但是上面的代码导致错误说,错误是由@count += 1
.我想不通为什么@count
有nil:NilClass
它的超?
(eval):5:in `bar=': undefined method `+' for nil:NilClass (NoMethodError)
Run Code Online (Sandbox Code Playgroud)
另一方面,@ serman给出了一个解决方案,@count
可以在实例方法中放置赋值,并且它可以工作.
class Class
def attr_count(attr_name)
#...
class_eval %Q{
def #{attr_name}= (attr_name)
@attr_name = attr_name
if @count
@count += 1
else
@count = 1
end
end
#...
}
end
end
Run Code Online (Sandbox Code Playgroud)
为什么更改变量范围有效?如何class_eval
执行以下字符串?
Sel*_*lug 12
它不是关于class_eval
它的@count
.如果你在类级别定义这个变量,它将class instance variable
不是一个instance variable
.
class Class
def attr_count(attr_name)
attr_name = attr_name.to_s
attr_reader attr_name # create the attribute's getter
class_eval %Q{
def #{attr_name}= (attr_name)
@attr_name = attr_name
if @count
@count += 1
else
@count = 1
end
end
def #{attr_name}
@attr_name
end
}
end
end
class Foo
attr_count :bar
end
f = Foo.new
f.bar = 1
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
5953 次 |
最近记录: |