hoodwink.d enhanced
RSS
2.0
XHTML
1.0

RedHanded

Ideas for Ruby 2 Manners #

by why in inspect

If I could clean up the little quacks that Ruby gives here and there.

Object.inspect

Currently:

 => #<Object:0xb7cd5ed0>
 => #<Book:0xb7cc4d00 @title="Gorbachev's Finger Tricks",
    @author="Gorbachev", @length=150>
 => #<File:ruby.h>

Slight polish:

 => (Object)
 => (Book @title="Gorbachev's Finger Tricks" 
    @author="Gorbachev" @length=150)
 => (File ruby.h)

Proc.inspect

Currently:

 => #<Proc:0xb7d19aa0@(irb):4>

Show arity?

 => (Proc |a,*b|)

Backtraces and Warnings

Currently:

 bin/tiny_wm.rb:4: parse error, unexpected '='
 $d = = X11::Display.new
       ^

 bin/tiny_wm.rb:2:in `require': no such file to load -- X11/Display (LoadError)
        from bin/tiny_wm.rb:2

 ArgumentError: wrong number of arguments (3 for 1)
        from (irb):1:in `gets'
        from (irb):1

 /home/why/bin/warn.rb:2: warning: parenthesize argument(s) for future version

Slight polish:

 ParseError in bin/tiny_wm.rb (line 4): 
   unexpected '='
   > $d = = X11::Display.new
   >       ^

 LoadError in bin/tiny_wm.rb (line 2) at `require':
   no such file to load -- X11/Display
        from bin/tiny_wm.rb (line 2)

 ArgumentError in irb (line 1) at `gets': 
   wrong number of arguments (3 for 1)
        from irb (line 1)

 Warning in /home/why/bin/warn.rb (line 2):
   parenthesize argument(s) for future version

We should avoid wrapping the `message’ inside the initial line of a backtrace. It is often the most crucial part.

It sure would be nice to have the ability to customize the look of your backtraces. To have backtrace objects like in Sydney. I’d like to brightly ANSI highlight the backtrace line which refers to $PROGRAM_NAME, give a dark color to trace lines from the stdlib and medium highlight everything else.

I’m sure all of you out there can give help here. But you know what I mean about some of these?

said on 14 Feb 2006 at 16:34

_why, be honest. Are you writing a window manager? If there were a rubidic sawfish, I’d be gleeful.

said on 14 Feb 2006 at 16:58

I agree with the Proc translation, but I do think the file/line number should be retained in the dump. That has helped me many times in debugging.

said on 14 Feb 2006 at 17:42

I would feel slightly saddened to see the memory address disappear out of the default inspect (I actually use it quite often in visual inspections), but I can see where you want to get rid of the clutter, especially for nested data structures.

I really like the idea of adding the arity to Proc#inspect. Also agree with Jamis on wanting to keep the definition location as well (though maybe via a separate method than inspect?).

As for backtraces, I’m pretty sure Exception#backtrace already exists, but only returning an array of strings, rather than a Backtrace object. Couldn’t be too hard to meta-hack that, right? I might take a stab at it when I get a spare moment, if no one else has by then.

said on 14 Feb 2006 at 17:49

Hmm. +1 on Proc arity and backtrace objects.

I kind of like the #<...> notation, though. It’s got a long and distinguished history in lisp-land. Also I agree with lukfugl that having the address is terribly handy at times. If not the address, at least include the object id to distinguish.

said on 14 Feb 2006 at 17:50

Well, actually () notation has a long and distinguished history in lisp-land. Just not for “internal” objects.

Eh, you know what I mean.

said on 14 Feb 2006 at 17:53

So, why IDs for objects? Just think of the clutter it would add for hashes and arrays.

I kind of like #<...> also. Still, the parens give an O shape for Object. Again, think of the simplicity we use when displaying hashes and arrays. REXML shows XML documents as <html>..</html> in inspect.

said on 14 Feb 2006 at 18:00
 => [(Book @title="Catcher in the Rye"), (Book @title="The Adventures of Huckleberry Finn")]

 => (Shelf @books=[(Book @title="Catcher in the Rye"), (Book @title="The Adventures of Huckleberry Finn")])

 => (RSS::Feed @updated_at=Tue Feb 14 18:52:31 EST 2006 @cache_file=(File /tmp/feed.cache))

Yes, let’s also cite how Time is displayed unadorned.

said on 14 Feb 2006 at 18:03

Hmm. Hashes and arrays are more … nondescript … normally, their specific identity doesn’t matter so much. They wear the same teeshirts and mingle in the crowd. Less so for many other sorts.

I think with object ids, I’d be mostly happy with the status quo as far as who inspects with a pointer and who doesn’t.

There are exceptions to all this I know, but I guess we’re talking about the defaults?

said on 14 Feb 2006 at 18:08

Where the thing with ids comes in best is with opaque objects (like from C extensions).

If the default inspect only showed ids/pointers for RStruct and that sort, maybe that would be okay.

I have to say the “clean look” is growing on me.

said on 14 Feb 2006 at 18:09

why: “So, why IDs for objects?”

I’ll often rely on Object#inspect showing (currently/proposed) the address/object_id of the object for quick verification against other objects that it is, in fact, the very same object. That right there is my primary use for Object#inspect.

But as I mentioned above, I can see where the clutter is a problem in Hashes and Arrays and other objects that contain many other objects. Maybe we could use a “verbose” flag argument to #inspect?

said on 14 Feb 2006 at 18:10

I would vote that Object#inspect output include the object_id. I’ve used this many times to check correctness of sharing at a glance.

On the other hand, it would be nice to be able to set a list of things to show. Add a Proc for object_id, one for instance data, one for anything else we can image. Or maybe I am thinking to generally.

said on 14 Feb 2006 at 18:16

So the object ids themselves aren’t particularly interesting, but being able to see if two particular objects are the same (in-memory) object or not is. That is, it’s the links that are interesting, not the actual values.

YAML makes this pretty clear, since you can see with the &1/*1 where duplicated structures are without needing to have addresses everywhere.

said on 14 Feb 2006 at 18:17

lukfugl: I don’t know, it seems like at that point you’re almost better off just calling Object#object_id direct-like.

Even if you add a verbose flag, you’d still have to convince Kernel#p and many other friends to use it.

said on 14 Feb 2006 at 18:18

Interestingly, I started using YAML for debugging dumps on Sunday night for exactly that reason.

said on 14 Feb 2006 at 18:20

glasser: I guess the other thing is hacking C extensions. Being able to get a C pointer right out of there from the Ruby prompt is nice sometimes.

But that would be covered by the previously mentioned pointers-only-for-RStruct motion.

said on 14 Feb 2006 at 18:32

MenTalguY: ”I don’t know, it seems like at that point you’re almost better off just calling Object#object_id direct-like.”

That’s what I was thinking too, and almost said so, but then reflected that every now and then I do want to see both the object_id and the structure, and wouldn’t want to have to call both. And I’d be satisfied with puts obj.inspect(true) versus p obj (ie. Kernel#p can go ahead and use the default of non-verbose).

said on 14 Feb 2006 at 18:34
Maybe not as drastic while still keeping the errors consistent. Less verbose output while still keeping the content is more usable.
bin/tiny_wm.rb:4 ParseError: unexpected '='
   > $d = = X11::Display.new
   >       ^

bin/tiny_wm.rb:2 LoadError: `require' no such file to load -- X11/Display
irb:1 ArgumentError: `gets' wrong number of arguments (3 for 1)
/home/why/bin/warn.rb:2 Warning: parenthesize argument(s) for future version
said on 14 Feb 2006 at 18:46

Great comments, the duplicate object situation and all that.

Try looking away from your own particular needs and examining the general need for friendliness at the prompt. I am very happy with the way Ruby is right now, but only because I give it a flattering light in my mind.

Think of the IRB prompt:

 irb(main):001:0>

Now I understand it. There’s useful stuff there. But I still prefer to cut it down to:

 >>

These characters are each of them important at this level. Does Jamis really need __FILE__ and __LINE__ in his inspect? Or could we offer more enough distinguishing properties of the block that make it just as recognizable? Or could inspect show simple summaries while still making details available?

said on 14 Feb 2006 at 19:56

I like where you’re going with this. It’d be nice to have that inspect clutter organized and out of the way. Focus it on what will help us humans quickly grok the object map or whatever we’re looking at.

said on 14 Feb 2006 at 20:01

I’d like an easy way to process filenames in a backtrace to remove the full path (not by default of course). Especially with delivered software, /local/ruby-1.8.4/lib/ruby/1.8/site_ruby/finally_something_interesting.rb:42; is painful sometimes.

said on 14 Feb 2006 at 20:04

Hey! My “i” tags worked in the preview but not in the post!

said on 15 Feb 2006 at 00:40
I suggest
p a   => (Object)
$verbose_inspect=true
p a   => (Object:0x2c36400)
and
ruby -e 'p $verbose_inspect'
  false
ruby -v -e 'p $verbose_inspect'
  true
Which I would think would be ideal, when I want to see general structure of some obect, I get just that, and when I’m in the mood for searching proper object sharing, I can just hit the switch and be done with it.
said on 15 Feb 2006 at 00:58

These are nice ideas, and I’m a huge fan of polishing areas like this.

My pet peeve: why are Array#to_s and Hash#to_s so useless? When is squishing all keys/values together ever what you want? Even if you set $, they aren’t that useful.

said on 15 Feb 2006 at 01:10

Not sure whether you’d be willing to take ideas from those guys, but within Eclipse’s Java debugger, cryptic object IDs are made readable by simply assigning them consecutive numbers during a debugging session. So you’ll easily see that object 6 and object 7 are different …

said on 15 Feb 2006 at 11:36

In IRB , where you see lots of inspect spills, I think it would be confusing to see lots of (Object 1) and try to remember that they’re different. Not too sure, though, I don’t know.

said on 15 Feb 2006 at 12:37

Once again, I’m late to the party…

My suggestion for Ruby 2:

I always thought it would be nice to have a Block class.

{ puts “This is a block!” }.class #=>Block

b = { puts “This is a block!” } b.to_s #=> “puts \”This is a block!\”“

In this context b wouldn’t be a closure (or a Proc object) but could be converted to a Proc object later in a different binding: b.to_proc.call

Blocks would be convertable easily to procs: b.to_proc OR: Proc.new b

Blocks would be serializeable (hence the to_s)... though Procs still wouldn’t be (but that’s OK).

and of course it would be great to be able to do:

b.to_ast

...but now I’m really dreaming.

said on 15 Feb 2006 at 13:38

FWIW , I’d like to have re-eval()uable output for objects, but I guess this would require much more syntax hacking than simple inspect override :(

said on 01 Mar 2006 at 05:06

What’s the Ruby answer to ipython?

Comments are closed for this entry.