thesecretmaster
thesecretmaster

Reputation: 1984

Add variable to main

For a gem I'm working on I need to add a variable to main, preferably a local variable, but instance works as well. I've been trying to use Object.instance_variable_set, but have made no progress that way. How can I accomplish this?

Clarification

I need to set the instance variable from a module within main.

Here is my situation:

module MyGem::Submodule
    def self.add_variable_to_main
        Object.instance_variable_set(:@var,"value")
    end
    def self.recieve_variable_from_main
        Object.instance_variable_get(:@var)
    end
    def self.store_block
        @@block=&block
    end
    def self.call_block
        add_variable_to_main
        @@block.call
        puts recieve_variable_from_main
    end
end

class Object
    include MyGem::Submodule
end

store_block do
    @var = "Var is #{@var}"
end

call_block

I also asked this question about the same problem, it has additional details.

Upvotes: 0

Views: 51

Answers (2)

Jörg W Mittag
Jörg W Mittag

Reputation: 369556

main is an object, objects can't have local variables. Local variables belong to lexical scopes, not objects.

You can simply assign to an instance variable in the context of main:

@ivar = 42

Now main has an instance variable @ivar with a value of 42.

Object#instance_variable_set works the same way:

instance_variable_set(:@ivar, 42)

If you are not within the context of main, you can access the top-level Binding via the global constant TOPLEVEL_BINDING, and the main object itself via TOPLEVEL_BINDING.receiver, since main is the implicit receiver, i.e. self at the top-level:

module Foo
  TOPLEVEL_BINDING.receiver.instance_variable_set(:@ivar, 42)
end

@ivar # => 42

Upvotes: 4

Aetherus
Aetherus

Reputation: 8898

There is a constant TOPLEVEL_BINDING that stores the binding of main. You can set instance variables to main from anywhere with that binding.

module Foo
  TOPLEVEL_BINDING.eval '@foo = :bar'
end

@foo  #=> :bar

Upvotes: 2

Related Questions