Pregunta

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]?

¿Fue útil?

Solución

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top