Like python's dir(), except better...


M

MonkeeSage

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...4?lnk=gst&q=python+dir()#msg_77d85f05e1ae8e66
 
Ad

Advertisements

R

Robert Dober

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
 
R

Robert Dober

Quoth Robert Dober:

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.

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

Robert
 
R

Robert Klemme

2007/11/29 said:
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
 
M

MonkeeSage

2007/11/29 said:
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

Example please?

Regards,
Jordan
 
M

MonkeeSage

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

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
 
Ad

Advertisements

M

MonkeeSage

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

Bug...#def should be returning nil

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

Regards,
Jordan
 
T

Todd Benson

2007/11/29, MonkeeSage <[email protected]>:
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

Example please?

Regards,
Jordan

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

Todd
 
M

MonkeeSage

2007/11/29, MonkeeSage <[email protected]>:
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
Example please?
Regards,
Jordan

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

Todd

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
 
Ad

Advertisements

R

Robert Dober

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
 

Top