Local variables can't be accessed from outside, right?

Discussion in 'Ruby' started by Michael Winterstein, Nov 28, 2009.

  1. Hi, I've been trying to figure out metaprogramming and I've mostly got
    it figured out, but in doing so I ran across this example:

    class A
    def initialize
    @a = 11
    @@a = 22
    a = 33
    end
    @a = 1
    @@a = 2
    a = 3
    end


    This was given as a posed question (can you access all the variables)
    and a particular order of the output was given (specifically, 1 2 3 11
    22 33). Getting at the instance variables, and even the class variables
    doesn't seem that hard to me. But it seems to me there's no way to get
    at the local variable a's. The way it was asked makes me think it might
    be possible, but I'm reasonably sure it isn't.

    However, I'm fairly new to Ruby and just wrapping my mind around the
    metaprogramming ideas and realize I could easily be missing something.

    I think a trick like puts A.new would be a lame solution, as would
    finding it somehow in memory after the class definition end statement
    (though that might be interesting to know if Ruby can do that).
    --
    Posted via http://www.ruby-forum.com/.
     
    Michael Winterstein, Nov 28, 2009
    #1
    1. Advertising

  2. Michael Winterstein wrote:
    > Hi, I've been trying to figure out metaprogramming and I've mostly got
    > it figured out, but in doing so I ran across this example:
    >
    > class A
    > def initialize
    > @a = 11
    > @@a = 22
    > a = 33
    > end
    > @a = 1
    > @@a = 2
    > a = 3
    > end
    >
    >
    > This was given as a posed question (can you access all the variables)
    > and a particular order of the output was given (specifically, 1 2 3 11
    > 22 33). Getting at the instance variables, and even the class variables
    > doesn't seem that hard to me. But it seems to me there's no way to get
    > at the local variable a's. The way it was asked makes me think it might
    > be possible, but I'm reasonably sure it isn't.
    >
    > However, I'm fairly new to Ruby and just wrapping my mind around the
    > metaprogramming ideas and realize I could easily be missing something.
    >
    > I think a trick like puts A.new would be a lame solution,


    Well, it would be the only solution to a lame question. :)

    > finding it somehow in memory after the class definition end statement
    > (though that might be interesting to know if Ruby can do that).


    Sort of. Remember, a class definition is executable code. Does that
    give you an idea? It should.

    Best,
    --
    Marnen Laibow-Koser
    http://www.marnen.org

    --
    Posted via http://www.ruby-forum.com/.
     
    Marnen Laibow-Koser, Nov 28, 2009
    #2
    1. Advertising

  3. On Friday 27 November 2009 11:56:43 pm Michael Winterstein wrote:
    > Hi, I've been trying to figure out metaprogramming and I've mostly got
    > it figured out, but in doing so I ran across this example:
    >
    > class A
    > def initialize
    > @a = 11
    > @@a = 22
    > a = 33
    > end
    > @a = 1
    > @@a = 2
    > a = 3
    > end
    >
    >
    > This was given as a posed question (can you access all the variables)
    > and a particular order of the output was given (specifically, 1 2 3 11
    > 22 33).


    > I think a trick like puts A.new would be a lame solution,


    That actually wouldn't work, though I can see why you think it'd be lame.

    Anyway, as far as I know, there are only a few ways to access a local
    variable:

    You could define a= -- for example,

    def a=(value)
    puts a
    end

    The problem is, I can't actually get this to work reliably. It really seems
    like assignment of this kind would only work if you did

    self.a = 33

    So, with that discarded, I don't think it's possible to get access to these
    local variables with the class as written, at least not cleanly. You could
    probably figure out (programatically) where the class is defined, and then
    parse the source.

    Other than that, the only way I know of getting at local variables is through
    the binding object, which you'd have to get either from inside the code, or
    from something called from that code -- but that class doesn't seem to call
    any methods from anywhere you care about, so that doesn't work.
     
    David Masover, Nov 28, 2009
    #3
  4. [Note: parts of this message were removed to make it a legal post.]

    class_local_a = class A
    def initialize
    @a = 11
    @@a = 22
    a = 33
    end
    @a = 1
    @@a = 2
    a = 3
    end

    p A.instance_variable_get:)@a) #ok

    p A.class_variable_get:)@@a) if RUBY_VERSION > '1.9'
    class A; p @@a end if RUBY_VERSION < '1.9'

    # a little tricky, sure
    p class_local_a

    p A.new.instance_variable_get:)@a)

    p A.class_variable_get:)@@a) if RUBY_VERSION > '1.9'
    class A; p @@a end if RUBY_VERSION < '1.9'

    p A.new.method:)initialize).call



    I didn't find other way to get the result of class A ... end like a if or
    case result.
    Very weared a class' instance variable(1)
    Does it have any interest?

    2009/11/28 David Masover <>

    > On Friday 27 November 2009 11:56:43 pm Michael Winterstein wrote:
    > > Hi, I've been trying to figure out metaprogramming and I've mostly got
    > > it figured out, but in doing so I ran across this example:
    > >
    > > class A
    > > def initialize
    > > @a = 11
    > > @@a = 22
    > > a = 33
    > > end
    > > @a = 1
    > > @@a = 2
    > > a = 3
    > > end
    > >
    > >
    > > This was given as a posed question (can you access all the variables)
    > > and a particular order of the output was given (specifically, 1 2 3 11
    > > 22 33).

    >
    > > I think a trick like puts A.new would be a lame solution,

    >
    > That actually wouldn't work, though I can see why you think it'd be lame.
    >
    > Anyway, as far as I know, there are only a few ways to access a local
    > variable:
    >
    > You could define a= -- for example,
    >
    > def a=(value)
    > puts a
    > end
    >
    > The problem is, I can't actually get this to work reliably. It really seems
    > like assignment of this kind would only work if you did
    >
    > self.a = 33
    >
    > So, with that discarded, I don't think it's possible to get access to these
    > local variables with the class as written, at least not cleanly. You could
    > probably figure out (programatically) where the class is defined, and then
    > parse the source.
    >
    > Other than that, the only way I know of getting at local variables is
    > through
    > the binding object, which you'd have to get either from inside the code, or
    > from something called from that code -- but that class doesn't seem to call
    > any methods from anywhere you care about, so that doesn't work.
    >
    >
     
    Benoit Daloze, Nov 28, 2009
    #4
  5. Benoit Daloze wrote:

    >
    > I didn't find other way to get the result of class A ... end like a if
    > or
    > case result.
    > Very weared a class' instance variable(1)
    > Does it have any interest?
    >


    No, it's just an example for learning about metaprogramming. Which is
    why it seems strange; the local variables can only be 'accessed' because
    they happen to be return values.

    I did learn something I didn't know, however :

    class A
    puts "Local variables: #{local_variables}"
    puts "Instance variables: #{instance_variables}"
    a = 5
    @a = 6
    puts "Local variables: #{local_variables}"
    puts "Instance variables: #{instance_variables}"
    end

    Local variables: a
    Instance variables:
    Local variables: a
    Instance variables: @a

    So local variables exist in some ethereal void after the code is scanned
    but before they can be used; not so with instance variables. That makes
    some sense. But this also lets you do this eval weirdness.

    class B
    puts "#{local_variables.first} = #{eval(local_variables.first)},
    which is a #{eval(local_variables.first).class}"
    eval(local_variables.first + "=2")
    puts "#{local_variables.first} = #{eval(local_variables.first)},
    which is a #{eval(local_variables.first).class}"

    puts #{a} if a #=> NameError: undefined local variable or method
    'a' for B:Class
    a = 4
    puts "#{local_variables.first} = #{eval(local_variables.first)},
    which is a #{eval(local_variables.first).class}"
    end

    With the error commented out, this gives:
    a = , which is a NilClass
    a = 2, which is a Fixnum
    a = 4, which is a Fixnum


    --
    Posted via http://www.ruby-forum.com/.
     
    Michael Winterstein, Nov 28, 2009
    #5
  6. Michael Winterstein

    pharrington Guest

    On Nov 28, 1:15 pm, Michael Winterstein <>
    wrote:
    > Benoit Daloze wrote:
    >
    > > I didn't find other way to get the result of class A ... end like a if
    > > or
    > > case result.
    > > Very weared a class' instance variable(1)
    > > Does it have any interest?

    >
    > No, it's just an example for learning about metaprogramming.  Which is
    > why it seems strange; the local variables can only be 'accessed' because
    > they happen to be return values.
    >
    > I did learn something I didn't know, however :
    >
    > class A
    >     puts "Local variables: #{local_variables}"
    >     puts "Instance variables: #{instance_variables}"
    >     a = 5
    >     @a = 6
    >     puts "Local variables: #{local_variables}"
    >     puts "Instance variables: #{instance_variables}"
    > end
    >
    > Local variables: a
    > Instance variables:
    > Local variables: a
    > Instance variables: @a
    >
    > So local variables exist in some ethereal void after the code is scanned
    > but before they can be used; not so with instance variables.  That makes
    > some sense.  But this also lets you do this eval weirdness.
    >

    From what I understand, this is because local variables are created
    when code is *parsed*, not actually run (as method resolution would be
    even more painful if the interpreter had to first search the object
    tree for a particular instance method every time a new local variable
    was defined)
     
    pharrington, Nov 28, 2009
    #6
  7. On Sat, Nov 28, 2009 at 2:30 PM, pharrington <> wrote:
    > On Nov 28, 1:15=A0pm, Michael Winterstein <>
    > wrote:
    >> So local variables exist in some ethereal void after the code is scanned
    >> but before they can be used; not so with instance variables. =A0That mak=

    es
    >> some sense. =A0But this also lets you do this eval weirdness.
    >>

    > From what I understand, this is because local variables are created
    > when code is *parsed*, not actually run (as method resolution would be
    > even more painful if the interpreter had to first search the object
    > tree for a particular instance method every time a new local variable
    > was defined)


    Actually, for MRI, at compile time a local gets assigned an index
    which is used to dereference an element of an array of local variables
    pointed to by a structure called SCOPE there is a stack of these
    scopes which grows and shrinks as methods and blocks are called and
    returned..

    The actual local variables need to be unique for each method
    invocation or block evaluation.

    --=20
    Rick DeNatale

    Blog: http://talklikeaduck.denhaven2.com/
    Twitter: http://twitter.com/RickDeNatale
    WWR: http://www.workingwithrails.com/person/9021-rick-denatale
    LinkedIn: http://www.linkedin.com/in/rickdenatale
     
    Rick DeNatale, Nov 28, 2009
    #7
  8. p> From what I understand, this is because local variables are created
    p> when code is *parsed*, not actually run (as method resolution would be
    p> even more painful if the interpreter had to first search the object
    p> tree for a particular instance method every time a new local variable
    p> was defined)

    Ah! So local variables are created when parsed but instance and class
    variables are created at execution!

    I hope that's right because a lightbulb just turned on.
     
    Ralph Shnelvar, Nov 28, 2009
    #8
  9. Michael Winterstein

    pharrington Guest

    On Nov 28, 3:46 pm, Ralph Shnelvar <> wrote:
    > p> From what I understand, this is because local variables are created
    > p> when code is *parsed*, not actually run (as method resolution would be
    > p> even more painful if the interpreter had to first search the object
    > p> tree for a particular instance method every time a new local variable
    > p> was defined)
    >
    > Ah!  So local variables are created when parsed but instance and class
    > variables are created at execution!
    >
    > I hope that's right because a lightbulb just turned on.


    Well its not exactly right (as Rick DeNatale explained) buts its a
    simple way to picture what goes on.
     
    pharrington, Nov 28, 2009
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Daniel
    Replies:
    7
    Views:
    509
  2. Replies:
    2
    Views:
    1,298
    jacob navia
    Sep 14, 2006
  3. Sullivan WxPyQtKinter
    Replies:
    10
    Views:
    707
    Antoon Pardon
    Nov 8, 2007
  4. Daniel
    Replies:
    4
    Views:
    379
    Daniel
    Nov 2, 2010
  5. Daniel
    Replies:
    5
    Views:
    148
    kaeli
    Jan 26, 2004
Loading...

Share This Page