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/\.