List local_variables in a def by means of a method

Hello,

As I work with ruby in combination with a programs API , i'm not able
to use a debugger. (at least I think ::slight_smile:

So i'm looking for a way to list my variables.

This is what I have:

def listvar

聽聽instance_variables.each {|inst| puts "#{inst} is #{inst.class} and is
聽聽equal to #{eval(inst).inspect}" }

聽聽local_variables.each {|var| puts "#{var} is #{var.class} and is equal
to #{eval(var).inspect}" }

end

module Test

聽聽@foo = 'good'

聽聽def self.one
聽聽聽聽foo = 'good'
聽聽聽聽foo1 = 'better'
聽聽聽聽foo2 = 'somehing'
聽聽聽聽@foo.upcase!
聽聽聽聽listvar
聽聽end

聽聽def self.two
聽聽聽聽foo = 1
聽聽聽聽foo1 = 2
聽聽聽聽foo2 = 3
聽聽聽聽@foo.reverse!
聽聽聽聽listvar
聽聽end

end
Test.one ==> @foo is String and is equal to "GOOD"
Test.two ==> @foo is String and is equal to "DOOG"

So it works for instance_variables only, not for local_variables.
If I want to list the local variables for self.one I have to do
it like this:

聽聽def self.one
聽聽聽聽foo = 'good'
聽聽聽聽foo1 = 'better'
聽聽聽聽foo2 = 'somehing'
聽聽聽聽@foo.upcase!
聽聽聽聽local_variables.each {|var| puts "#{var} is #{var.class} and is
equal to #{eval(var).inspect}" }
聽聽end

==>
foo is String and is equal to 1
foo1 is String and is equal to 2
foo2 is String and is equal to 3

But its not nice!!!!! How can i achieve this by just typing a command,
like with the instance_variables??

Thnx

Liquid

路路路

--
Posted via http://www.ruby-forum.com/.

You can't. The "listvar" method has a different scope than "one" or
"two", and thus different local variables. You could try passing a
binding to the "listvar" method, but I don't know if it's worth the
hassle.

-- Matma Rex

Bartosz Dziewo艅ski wrote in post #1058785:

You can't. The "listvar" method has a different scope than "one" or
"two", and thus different local variables. You could try passing a
binding to the "listvar" method, but I don't know if it's worth the
hassle.

-- Matma Rex

Thnx Matma,

It would be very convenient for me to get a list of my vars in a simple
way.
So once I'm through the hassle of writing the method ,I can use it over
and over again and enjoy!

But how can I use these bindings??

路路路

--
Posted via http://www.ruby-forum.com/\.

Like this:

路路路

--------
class A
聽聽def stuff
聽聽聽聽a = 4
聽聽聽聽foo = 'asd'
聽聽聽聽list_vars(binding())
聽聽end

聽聽def list_vars bnd
聽聽聽聽bnd.eval('local_variables').each{|var|
聽聽聽聽聽聽puts "#{var} is #{bnd.eval(var.to_s).class} and is equal to
#{bnd.eval(var.to_s).inspect}"
聽聽聽聽}
聽聽end
end

A.new.stuff
--------

This will print:

a is Fixnum and is equal to 4
foo is String and is equal to "asd"

The method "binding" will return a magical value that basically
contains the entire state of a script in this particular place. You
can then eval code as if it appeared in that place, and you will have
access to all variables available there.

-- Matma Rex

Thank you Bartosz

I can work from here!

路路路

--
Posted via http://www.ruby-forum.com/.

Ronnie Aa wrote in post #1058797:

Thank you Bartosz

I can work from here!

Aside: every time you pass a block, you are also passing a binding
implicitly. So you can change this to:

class A
  def stuff
    a = 4
    foo = 'asd'
    list_vars {}
  end

  def list_vars &blk
    bnd = blk.binding
    bnd.eval('local_variables').each{|var|
      val = bnd.eval(var.to_s)
      puts "#{var} is #{val.class} and is equal to #{val.inspect}"
    }
  end
end

A.new.stuff

If you can think of something useful to do with the block, then it will
look less odd than passing an empty one :slight_smile:

路路路

--
Posted via http://www.ruby-forum.com/\.