Like python's dir(), except better

People often want to look at an object's attributes when debugging.
[1] Python has a handy dir() function that lists the attributes of an
object. And I use it tons. I often use obj.methods.sort in ruby for
the same purpose. But that doesn't show me class variables. There are
a handful of reflection functions to show different types of metadata
about an object.

So...this is my attempt to create a "Super dir() with extra-strength,
industrial, ruby power". I probably failed, and it's probably buggy as
I just hacked it together in about 15 minutes. In other words, I've
not tested it very extensively, YMMV (in fact your hair may
spontaneously catch on fire and you may start chanting backwards in
Latin...don't blame me; I've warned you!).

class DirObject
  def initialize(attrs=[])
    @attributes = attrs
  end
  def push(metadata)
    @attributes << metadata
  end
  def include?(test)
    @attributes.each { | key, value |
      return true if value.include?(test)
    }
    false
  end
  def show
    puts @attributes.map { | key, value |
      #key + ":\n " + value.join("\n ")
      key + ":\n " + value.inspect
    }.join("\n\n")
    self
  end
end

class Object
private
  def _get_metadata(meta)
    begin
      send(meta)
    rescue NameError
      []
    end
  end
  def _format_meta(meta)
    unless (idx = meta.index("_")).nil?
      meta[0] = meta[0].chr.upcase
      meta[idx+1] = meta[idx+1].chr.upcase
      meta = meta[0..idx-1] + " " + meta[idx+1..-1]
    else
      meta[0] = meta[0].chr.upcase
      meta
    end
  end
  def _do_metadata(meta, dirobj)
    data = _get_metadata(meta)
    unless data.empty?
      meta = _format_meta(meta)
      dirobj.push([meta, data.sort])
    end
    dirobj
  end
public
  def dir(verbose=false)
    dirobj = DirObject.new
    _do_metadata("class_variables", dirobj)
    _do_metadata("instance_variables", dirobj)
    _do_metadata("methods", dirobj)
    _do_metadata("instance_methods", dirobj)
    if verbose
      _do_metadata("private_methods", dirobj)
      _do_metadata("private_instance_methods", dirobj)
      _do_metadata("protected_methods", dirobj)
      _do_metadata("protected_instance_methods", dirobj)
      _do_metadata("public_methods", dirobj)
      _do_metadata("public_instance_methods", dirobj)
      _do_metadata("singleton_methods", dirobj)
    end
    dirobj
  end
  def ls(verbose=false)
    dir(verbose).show
  end
end

Comments, corrections and criticisms welcome!

Ps. Object#dir actually prints the metadata (like python's dir()), and
#ls just gives you a DirObject which is really only useful to do an
includes? on (which searches for a value through the entire metadata).

http://monkeesage.prohosts.org/ruby/dir.rb [right-click save-as]

Regards,
Jordan

[1]
http://groups.google.com/group/comp.lang.ruby/browse_thread/thread/d107b1318bbfdfd1/afa5a69d30007a64?lnk=gst&q=python+dir()#msg_77d85f05e1ae8e66

Great idea!
I would however leave Object alone, and put all code into DirObject.
Thus DirObject has to explore Object which might be a little bit
harder and slower, but you definitely do not want to mess with Object,
right?
Just a short example of what I have in mind
__do_metadata("methods"n, do) becomes

def DirMethods#add_methods( of_object )
   of_object.methods ...

an_object.dir # which would be distroyed by overloading *very often*
anyway becomes

DirObject.new( an_object ).

Cheers
Robert

···

On Nov 29, 2007 3:40 AM, MonkeeSage <MonkeeSage@gmail.com> wrote:
--

http://ruby-smalltalk.blogspot.com/

---
All truth passes through three stages. First, it is ridiculed. Second,
it is violently opposed. Third, it is accepted as being self-evident.
Schopenhauer (attr.)

You can view the attributes quite conveniently with pp (you'll see
instance variables nicely nested and indented as a tree).

Kind regards

robert

···

2007/11/29, MonkeeSage <MonkeeSage@gmail.com>:

People often want to look at an object's attributes when debugging.
[1] Python has a handy dir() function that lists the attributes of an
object. And I use it tons. I often use obj.methods.sort in ruby for
the same purpose.

--
use.inject do |as, often| as.you_can - without end

Bug...#def should be returning nil

  def ls(verbose=false)
    dir(verbose).show
    nil
  end

Regards,
Jordan

···

On Nov 28, 8:37 pm, MonkeeSage <MonkeeS...@gmail.com> wrote:

People often want to look at an object's attributes when debugging.
[1] Python has a handy dir() function that lists the attributes of an
object. And I use it tons. I often use obj.methods.sort in ruby for
the same purpose. But that doesn't show me class variables. There are
a handful of reflection functions to show different types of metadata
about an object.

So...this is my attempt to create a "Super dir() with extra-strength,
industrial, ruby power". I probably failed, and it's probably buggy as
I just hacked it together in about 15 minutes. In other words, I've
not tested it very extensively, YMMV (in fact your hair may
spontaneously catch on fire and you may start chanting backwards in
Latin...don't blame me; I've warned you!).

class DirObject
  def initialize(attrs=)
    @attributes = attrs
  end
  def push(metadata)
    @attributes << metadata
  end
  def include?(test)
    @attributes.each { | key, value |
      return true if value.include?(test)
    }
    false
  end
  def show
    puts @attributes.map { | key, value |
      #key + ":\n " + value.join("\n ")
      key + ":\n " + value.inspect
    }.join("\n\n")
    self
  end
end

class Object
private
  def _get_metadata(meta)
    begin
      send(meta)
    rescue NameError
      
    end
  end
  def _format_meta(meta)
    unless (idx = meta.index("_")).nil?
      meta[0] = meta[0].chr.upcase
      meta[idx+1] = meta[idx+1].chr.upcase
      meta = meta[0..idx-1] + " " + meta[idx+1..-1]
    else
      meta[0] = meta[0].chr.upcase
      meta
    end
  end
  def _do_metadata(meta, dirobj)
    data = _get_metadata(meta)
    unless data.empty?
      meta = _format_meta(meta)
      dirobj.push([meta, data.sort])
    end
    dirobj
  end
public
  def dir(verbose=false)
    dirobj = DirObject.new
    _do_metadata("class_variables", dirobj)
    _do_metadata("instance_variables", dirobj)
    _do_metadata("methods", dirobj)
    _do_metadata("instance_methods", dirobj)
    if verbose
      _do_metadata("private_methods", dirobj)
      _do_metadata("private_instance_methods", dirobj)
      _do_metadata("protected_methods", dirobj)
      _do_metadata("protected_instance_methods", dirobj)
      _do_metadata("public_methods", dirobj)
      _do_metadata("public_instance_methods", dirobj)
      _do_metadata("singleton_methods", dirobj)
    end
    dirobj
  end
  def ls(verbose=false)
    dir(verbose).show
  end
end

Comments, corrections and criticisms welcome!

Ps. Object#dir actually prints the metadata (like python's dir()), and
#ls just gives you a DirObject which is really only useful to do an
includes? on (which searches for a value through the entire metadata).

http://monkeesage.prohosts.org/ruby/dir.rb[right-click save-as]

Regards,
Jordan

[1]http://groups.google.com/group/comp.lang.ruby/browse_thread/thread/d1\.\.\.

Quoth Robert Dober:

···

On Nov 29, 2007 3:40 AM, MonkeeSage <MonkeeSage@gmail.com> wrote:
Great idea!
I would however leave Object alone, and put all code into DirObject.
Thus DirObject has to explore Object which might be a little bit
harder and slower, but you definitely do not want to mess with Object,
right?
Just a short example of what I have in mind
__do_metadata("methods"n, do) becomes

def DirMethods#add_methods( of_object )
   of_object.methods ...

an_object.dir # which would be distroyed by overloading *very often*
anyway becomes

DirObject.new( an_object ).

Cheers
Robert

Well, it's not like it's *wrong* to mess with object as long as you're not
overwriting stuff. Or so it seems to me.

Regards,
--
Konrad Meyer <konrad@tylerc.org> http://konrad.sobertillnoon.com/

Example please?

Regards,
Jordan

···

On Nov 29, 7:30 am, Robert Klemme <shortcut...@googlemail.com> wrote:

2007/11/29, MonkeeSage <MonkeeS...@gmail.com>:

> People often want to look at an object's attributes when debugging.
> [1] Python has a handy dir() function that lists the attributes of an
> object. And I use it tons. I often use obj.methods.sort in ruby for
> the same purpose.

You can view the attributes quite conveniently with pp (you'll see
instance variables nicely nested and indented as a tree).

Kind regards

robert

--
use.inject do |as, often| as.you_can - without end

I don't know? I've never heard that extending Object was bad? Seems
like, if I want a method to operate on all instances of Object,
putting the method in class Object is way to do it. I dislike the idea
of initializing objects as a subclass to get #dir on them.

Regards,
Jordan

···

On Nov 29, 1:06 am, Robert Dober <robert.do...@gmail.com> wrote:

On Nov 29, 2007 3:40 AM, MonkeeSage <MonkeeS...@gmail.com> wrote:
Great idea!
I would however leave Object alone, and put all code into DirObject.
Thus DirObject has to explore Object which might be a little bit
harder and slower, but you definitely do not want to mess with Object,
right?
Just a short example of what I have in mind
__do_metadata("methods"n, do) becomes

def DirMethods#add_methods( of_object )
   of_object.methods ...

an_object.dir # which would be distroyed by overloading *very often*
anyway becomes

DirObject.new( an_object ).

Cheers
Robert
--

http://ruby-smalltalk.blogspot.com/

---
All truth passes through three stages. First, it is ridiculed. Second,
it is violently opposed. Third, it is accepted as being self-evident.
Schopenhauer (attr.)

I am not sure about the principle but please do not forget that people
will overwrite *your stuff*.

Robert

···

On Nov 29, 2007 8:20 AM, Konrad Meyer <konrad@tylerc.org> wrote:

Quoth Robert Dober:
> On Nov 29, 2007 3:40 AM, MonkeeSage <MonkeeSage@gmail.com> wrote:
> Great idea!
> I would however leave Object alone, and put all code into DirObject.
> Thus DirObject has to explore Object which might be a little bit
> harder and slower, but you definitely do not want to mess with Object,
> right?
> Just a short example of what I have in mind
> __do_metadata("methods"n, do) becomes
>
> def DirMethods#add_methods( of_object )
> of_object.methods ...
>
> an_object.dir # which would be distroyed by overloading *very often*
> anyway becomes
>
> DirObject.new( an_object ).
>
> Cheers
> Robert

Well, it's not like it's *wrong* to mess with object as long as you're not
overwriting stuff. Or so it seems to me.

--

http://ruby-smalltalk.blogspot.com/

---
All truth passes through three stages. First, it is ridiculed. Second,
it is violently opposed. Third, it is accepted as being self-evident.
Schopenhauer (attr.)

>
> > People often want to look at an object's attributes when debugging.
> > [1] Python has a handy dir() function that lists the attributes of an
> > object. And I use it tons. I often use obj.methods.sort in ruby for
> > the same purpose.
>
> You can view the attributes quite conveniently with pp (you'll see
> instance variables nicely nested and indented as a tree).
>
> Kind regards
>
> robert
>
> --
> use.inject do |as, often| as.you_can - without end

Example please?

Regards,
Jordan

require 'pp'

=> true

class C; def initialize; @var = 1; end; end

=> nil

pp( C.new )

#<C:0x2d8d3c4 @var=1>
=> nil

Todd

···

On Nov 29, 2007 4:45 PM, MonkeeSage <MonkeeSage@gmail.com> wrote:

On Nov 29, 7:30 am, Robert Klemme <shortcut...@googlemail.com> wrote:
> 2007/11/29, MonkeeSage <MonkeeS...@gmail.com>:

> Great idea!
> I would however leave Object alone, and put all code into DirObject.
> Thus DirObject has to explore Object which might be a little bit
> harder and slower, but you definitely do not want to mess with Object,
> right?
> Just a short example of what I have in mind
> __do_metadata("methods"n, do) becomes
>
> def DirMethods#add_methods( of_object )
> of_object.methods ...
>
> an_object.dir # which would be distroyed by overloading *very often*
> anyway becomes
>
> DirObject.new( an_object ).
>
> Cheers
> Robert
> --
>
> http://ruby-smalltalk.blogspot.com/
>
> ---
> All truth passes through three stages. First, it is ridiculed. Second,
> it is violently opposed. Third, it is accepted as being self-evident.
> Schopenhauer (attr.)

I don't know? I've never heard that extending Object was bad?

No it is not, I do it a lot, but it depends on your intentions.
If you are doing this for your own this is fine. However I believe
that such a feature shall rather play the rule
of a framework, well than there is really not much doubt IMHO,
extending Object is bad, your functionality will
just go away, especially as you are using such a common method name as #dir.

like, if I want a method to operate on all instances of Object,
putting the method in class Object is way to do it. I dislike the idea
of initializing objects as a subclass to get #dir on them.

I do not interpret my code that way at all, a DirObject is an object
that has gathered information of a contained object, seems pretty much
straight forward to me??
And nobody will break it unless monkey patching it.

BTW do you not create a DirObject yourself in Object#dir?

Cheers
Robert

···

On Nov 30, 2007 12:05 AM, MonkeeSage <MonkeeSage@gmail.com> wrote:

On Nov 29, 1:06 am, Robert Dober <robert.do...@gmail.com> wrote:
> On Nov 29, 2007 3:40 AM, MonkeeSage <MonkeeS...@gmail.com> wrote:

--

http://ruby-smalltalk.blogspot.com/

---
All truth passes through three stages. First, it is ridiculed. Second,
it is violently opposed. Third, it is accepted as being self-evident.
Schopenhauer (attr.)

Thanks. I'm aware of that, but it doesn't show methods, class
variables, and so on, and many times it just gives you a to_s (e.g.,
pp([1,2,3])). I was of the impression that Robert was talking about
viewing *all* of the object's attributes with pp.

Regards,
Jordan

···

On Nov 29, 5:10 pm, Todd Benson <caduce...@gmail.com> wrote:

On Nov 29, 2007 4:45 PM, MonkeeSage <MonkeeS...@gmail.com> wrote:

> On Nov 29, 7:30 am, Robert Klemme <shortcut...@googlemail.com> wrote:
> > 2007/11/29, MonkeeSage <MonkeeS...@gmail.com>:

> > > People often want to look at an object's attributes when debugging.
> > > [1] Python has a handy dir() function that lists the attributes of an
> > > object. And I use it tons. I often use obj.methods.sort in ruby for
> > > the same purpose.

> > You can view the attributes quite conveniently with pp (you'll see
> > instance variables nicely nested and indented as a tree).

> > Kind regards

> > robert

> > --
> > use.inject do |as, often| as.you_can - without end

> Example please?

> Regards,
> Jordan

> require 'pp'
=> true
> class C; def initialize; @var = 1; end; end
=> nil
> pp( C.new )
#<C:0x2d8d3c4 @var=1>
=> nil

Todd