0

I'm trying to access an instance variable in the methods of a module.

module Filter
  def self.included(target)
    puts "INCLUDED: #{@var}"
    target.instance_variable_set(:@var, @var) # doesn't seem to work
  end

  def self.var=(var)
    @var = var
  end

  def self.var
    @var
  end

  def hello
    @var
  end

end

f = Filter
f.var = "hello"

puts "SET: #{f.var}"

class Main
  include Filter
end

m = Main.new

puts "HELLO: #{m.hello}"

It produces this output:

ruby test2.rb
SET: hello
INCLUDED: hello
HELLO: 

The last line "HELLO:" needs to output "HELLO: hello". How do I initialize the @var instance variable to make this happen?

1 Answer 1

2

As many-many others, you too are confused by the term "instance variable" here. It's an instance variable, all right, but it's not an instance you think about.

Remember, everything in ruby is an object. Even classes themselves.

  def self.included(target)
    puts "INCLUDED: #{@var}"
    target.instance_variable_set(:@var, @var) # doesn't seem to work
  end

So here you're setting instance variable on target (which would be a Class, most likely). Yet you're trying to read from instance of target.

m = Main.new

puts "HELLO: #{m.hello}"

This is where your variable is:

puts "The right HELLO: #{Main.instance_variable_get(:@var)}"

Naturally, it is not possible to set an instance variable (in this manner) on an instance that does not yet exist! Depending on what exactly you're after, different strategies can be implemented. I suggest you ask another, more refined question.

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks, yeah, it's a little confusing. I just need to be able to access @var when I call m.hello, which is the method included from the module. Any ideas?
@Vidar: this one option - def hello; self.class.instance_variable_get(:@var); end
Beware, though. If you change that @var, all instances of target will see the updated version. Not sure if it's desirable behaviour for you or not.
So how do I avoid that? That's exactly what I'm trying not to do. I used a class variable before (@@var) and got a race condition.
That's another question. Make it focused.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.