On Sun, Jul 20, 2003 at 04:42:16AM +0900, John W. Long wrote:
> Hi Mauricio,
> 
> > > No spaces are used when the element doesn't exsist in the other object.
> For
> > > example:
> >
> > OK, I see it now. Implementing this is however quite complicated (ie.
> > not as easy as what I'm doing now :)
> 
> Which may explain why your code was so clean :-). I'd like to see what would
> happen if you did add this functinality. I may try and do this myself if I
> have time this weekend and see how easy it is. But I agree the problem does
> get much more complicated when you add the spaces.

Not *much* more. I estimated I'd need 10 lines, it took 12:

batsman@tux-chan:/tmp$ diff -u objectdiff.good.rb objectdiff.rb  | unexpand  | expand -t 2
--- objectdiff.good.rb  2003-07-19 22:47:56.000000000 +0200
+++ objectdiff.rb 2003-07-19 23:00:31.000000000 +0200
@@ -59,7 +59,19 @@
      when Hash
        keys = obj.keys.sort{|a,b| a.to_s <=> b.to_s}
        r = "{"
+       count = 0
+       keys2 = other.keys.sort{|a,b| a.to_s <=> b.to_s} if Hash === other
        keys.each_with_index do |k, i|
+         if Hash === other
+           keys2.each_with_index do |key,n|
+             if key.to_s >= k.to_s
+               keys2 = keys2[n+1..-1]
+               break
+             end
+             r << " " * (object_to_s(other[key]).size + 4  +
+               key.inspect.size)
+           end
+         end
          if Hash === other and other.key?(k) and obj[k] == other[k]
            r << (i == 0? '': ' ') + "..."
          elsif Hash === other and other.key?(k)
@@ -175,7 +187,7 @@
    string_a, string_b = ObjectDiff.compare_hash(a, b)
    puts [string_a, string_b]
    assert_equal('{:a=>1, :b=>2, ... :d=>4}', string_a)
-   assert_equal('{:b=>3, ... :d=>5, :j=>2}', string_b)
+   assert_equal('{       :b=>3, ... :d=>5, :j=>2}', string_b)
  end
 end


> > > A couple of things I haven't figured out:
> > >
> > > 1. What does ruby use when outputting the object id for object.inspect?
> > > Either I can't get the formatting right, or it's not the object id.
> (Compare
> > > object_to_s with inspect.)
> >
> > It uses the address of the object:
>
> That makes sense. But it begs the question: how do you get the address of an
> object in ruby?

It's impossible AFAIK within plain Ruby. You can however write an
extension to do so, by doing:

(some .c file, name doesn't matter)
#include <ruby.h>

static
VALUE
get_address(VALUE class, VALUE obj)
{
 return INT2NUM((long)obj);
}

void
Init_GetAddress()
{
 rb_define_method(rb_mKernel, "get_address", get_address, 1);
}

extconf.rb:
require 'mkmf'

create_makefile('GetAddress')


and then within Ruby:
require 'GetAddress' # have to adjust path before and/or install extension

a = ""
p get_address(a)

> > > 2. How do you handle fringe classes that are descendants of Array, Hash,
> > > String, etc... intelligently? For instance say A < String and has an
> > > instance variable. How do you print this and note the difference? (Or
> should
> > > you even bother?)
> >
> > perhaps introducing a notation like
> > <MyArrayClass:0x12345678 [... 1, 2, ..., 3] @a=1>
> 
> So you would use the above whenever the object was a kind_of?(Array) but not
> a instance_of?(Array) ?

yes. I wouldn't expect that to happen very often, however.

-- 
 _           _                             
| |__   __ _| |_ ___ _ __ ___   __ _ _ __  
| '_ \ / _` | __/ __| '_ ` _ \ / _` | '_ \ 
| |_) | (_| | |_\__ \ | | | | | (_| | | | |
|_.__/ \__,_|\__|___/_| |_| |_|\__,_|_| |_|
	Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

And 1.1.81 is officially BugFree(tm), so if you receive any bug-reports
on it, you know they are just evil lies.
	-- Linus Torvalds