KnowledgeHub
Questions
Tags
Users
Search
Alex Rivera
|
Logout
Edit Question
Title
Body
I am using class_eval to write code to be executed under the context of current class. In the following code, I want to add a counter for changes of attribute values. 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 My understanding of class_eval is that it evaluates the block in the context of the runtime class - in my case, under class Foo . I expect the above code runs similar as : class Foo attr_count :bar @count = 0 def bar= (attr_name) @attr_name = attr_name @count += 1 end def bar @attr_name end end However the above code resulted in error saying, the error is caused by @count += 1 . I cannot figure out why @count has nil:NilClass as its super? (eval):5:in `bar=': undefined method `+' for nil:NilClass (NoMethodError) On the other hand, @selman has given a solution to put @count assignment within the instance method and it works. 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 Why changes the variable scope works? How does class_eval execute its following string?
Tags (comma-separated)
Save Edits
Cancel