Reputation: 17306
Apparently, Ruby can make a code block returning an instance variable's value with a symbol. Consider:
class Person
attr_accessor :fn
end
def give(n,&b)
i=0
while(i<n)
aa = Person.new
aa.fn = "name #{i}"
i=i+1
puts b.call(aa)
end
end
Now, both give(5, &:fn)
and give(5) {|x| x.fn}
give
name 0
name 1
name 2
name 3
name 4
=> nil
But what does &:fn
really mean? I know the ampersand can convert a Proc to a block such as
bb = Proc.new {|x| x.fn}
give(5, &bb)
So what does the symbol :fn
mean? Where can I see a documentation of its use like this? Can we use a symbol to access the instance variable, like say person:new
or person[:new]
?
Upvotes: 4
Views: 2133
Reputation: 35788
Simple. The statment
attr_accessor :fn
Doesn't define some sort of special instance variable thing. It declares two methods of (approximately) this form:
def fn
@fn
end
def fn=(v)
@fn=v
end
The Ruby "syntax" &:fn
is a symbol that the operator &
tries to convert to a proc. And, guess what? Symbol
implements to_proc
. Guess that that looks like:
def to_proc
Proc.new {|obj| obj.__send__(self)}
end
That captures self
, which is the symbol :fn
, which, on invocation, tells obj
to execute the method fn
, which returns the value of the instance variable.
EDIT: Answering the second part of the question, no and yes. With the syntax you say, no. But you can call a method from a symbol with BasicObject#__send__
and you can do the same for not attr_accessor
instance variables with Object#instance_variable_get
.
Upvotes: 4