[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Re: [SOLUTION] Object Browser (#8

Jamis Buck

11/22/2004 2:39:00 AM

R. Mark Volkmann wrote:
> I'm new to using gems. Can you tell me the command I need to run to get
> ruby-gtk2 so I can run your code?

Unfortunately, ruby-gtk2 is not a gem, nor is it in rpa. So you have to
install it the "hard" way--from source. If you're on Windows, it's even
harder: you have to install GTK2 first.

GTK2: http://w...
Ruby-GTK2 (part of Ruby-Gnome2): http://ruby-gnome2.sourc...

Having never used GTK in Windows, I have no idea how easy/hard it is to
get ruby-gtk2 running under Windows. YMMV. YHBW.

- Jamis

P.S.: A plea to the ruby-gnome2 folks: a gemmable version would be a
real boon. A similar plea to the RPA folks... ;)

>
> ----- Original Message ----- From: "Jamis Buck" <jgb3@email.byu.edu>
> To: "ruby-talk ML" <ruby-talk@ruby-lang.org>
> Sent: Sunday, November 21, 2004 6:48 PM
> Subject: [SOLUTION] Object Browser (#8)
>
>
>> Well, I was kind of waiting to see what other people came up with, but
>> since the list seems quiet on this topic, I guess I'll go ahead and post
>> first.
>>
>> This is a VERY rough implementation. It uses ruby-gtk2, and is one of my
>> first projects using that interface, so I've doubtless done all kinds of
>> things wrong. :) But it works.
>>
>> By default, it displays the "main" object. You can see the class,
>> superclass, instance/class variables, public/private/protected methods,
>> and constants (where any of them apply and are non-empty).
>>
>> I wanted to add the ability to modify values, but didn't quite have time
>> to get that far.
>>
>> This was a great quiz, though. I'd love to see a more sophisticated
>> version of this. I can use mine, for instance, to do a kind of
>> breakpoint in my code:
>>
>> ObjectBrowser.browse( @foo )
>>
>> And the program will stop, display the window, and wait for the window
>> to close before proceeding.
>>
>> Anyway. Comments?
>>
>> - Jamis
>>
>> --
>> Jamis Buck
>> jgb3@email.byu.edu
>> http://www.jamisbuck...
>>
>
>
> --------------------------------------------------------------------------------
>
>
>
>> require 'gtk2'
>>
>> DEFAULT_OBJECTBROWSER_ROOT = self
>>
>> class Object
>> alias :pre_objbrowser_inspect :inspect
>> def inspect
>> result = pre_objbrowser_inspect
>> result = $1 + " ...>" if result =~ /^(#<.*?:0x\w+) /
>> result
>> end
>> end
>>
>> module ObjectBrowser
>>
>> def browse( root = DEFAULT_OBJECTBROWSER_ROOT )
>> Interface.new( root ).display_and_wait
>> end
>> module_function :browse
>>
>> class Interface
>> def initialize( root = DEFAULT_OBJECTBROWSER_ROOT )
>> @root = root
>> Gtk.init
>> end
>>
>> def display
>> window = Window.new( @root )
>> window.show_all
>> end
>>
>> def display_and_wait
>> display
>> wait
>> end
>>
>> def wait
>> Gtk.main
>> end
>> end
>>
>> class Window < Gtk::Window
>> OBJECT = 1
>> CLASS = 2
>> INSTANCE_VARS = 3
>> PUBLIC_METHODS = 4
>> PROTECTED_METHODS = 5
>> PRIVATE_METHODS = 6
>> CLASS_VARS = 7
>> CONSTANTS = 8
>> SUPERCLASS = 9
>> STRING = 10
>> INSTANCE_METHODS = 11
>>
>> LABEL = 0
>> TYPE = 1
>> REF = 2
>>
>> def initialize( root )
>> super( Gtk::Window::TOPLEVEL )
>>
>> signal_connect "delete_event", &method( :on_delete )
>> signal_connect "destroy", &method( :on_destroy )
>>
>> vbox = Gtk::VBox.new
>> add(vbox)
>>
>> pane = Gtk::VPaned.new
>> vbox.add pane
>>
>> sw = Gtk::ScrolledWindow.new
>> sw.set_policy *[Gtk::POLICY_AUTOMATIC]*2
>> sw.shadow_type = Gtk::SHADOW_IN
>> pane.add sw
>>
>> @model = Gtk::TreeStore.new( String, Integer, Integer )
>> add_node( nil, root )
>>
>> @tree = Gtk::TreeView.new( @model )
>> @tree.set_size_request -1, 400
>>
>> renderer = Gtk::CellRendererText.new
>>
>> col = Gtk::TreeViewColumn.new( "Data", renderer )
>> col.set_cell_data_func renderer, &method( :on_cell_render )
>>
>> @tree.append_column col
>> @tree.expand_row Gtk::TreePath.new( "0" ), false
>>
>> @tree.signal_connect "row_expanded", &method( :on_row_expanded )
>>
>> sw.add @tree
>>
>> sw = Gtk::ScrolledWindow.new
>> sw.set_policy *[Gtk::POLICY_AUTOMATIC]*2
>> sw.shadow_type = Gtk::SHADOW_IN
>> pane.add sw
>>
>> @text = Gtk::TextView.new
>> sw.add @text
>>
>> set_default_size 650, 500
>> end
>>
>> def on_delete( widget, event )
>> false
>> end
>>
>> def on_destroy( widget )
>> Gtk.main_quit
>> end
>>
>> def on_cell_render( c, r, m, i )
>> case i[TYPE]
>> when OBJECT
>> obj = ObjectSpace._id2ref( i[REF].to_i )
>> r.text = "#{i[LABEL]}#{obj.inspect}"
>> when CLASS, SUPERCLASS
>> obj = ObjectSpace._id2ref( i[REF].to_i )
>> r.text = "#{i[LABEL]} #{obj.name}"
>> else
>> r.text = i[LABEL]
>> end
>> end
>>
>> def on_row_expanded( widget, iter, path )
>> unless iter.first_child[LABEL]
>> case iter[1]
>> when OBJECT, CLASS, SUPERCLASS then
>> obj = ObjectSpace._id2ref( iter[REF].to_i )
>> add_node iter, obj, iter.first_child
>> when INSTANCE_VARS then
>> obj = ObjectSpace._id2ref( iter.parent[REF].to_i )
>> initialize_vars_list( obj, iter, obj.instance_variables.sort,
>> :instance_variable_get )
>> when PUBLIC_METHODS then
>> obj = ObjectSpace._id2ref( iter.parent[REF].to_i )
>> initialize_methods_list( obj, iter,
>> obj.public_methods(false).sort )
>> when PROTECTED_METHODS then
>> obj = ObjectSpace._id2ref( iter.parent[REF].to_i )
>> initialize_methods_list( obj, iter,
>> obj.protected_methods(false).sort )
>> when PRIVATE_METHODS then
>> obj = ObjectSpace._id2ref( iter.parent[REF].to_i )
>> initialize_methods_list( obj, iter,
>> obj.private_methods(false).sort )
>> when INSTANCE_METHODS then
>> obj = ObjectSpace._id2ref( iter.parent[REF].to_i )
>> initialize_methods_list( obj, iter,
>> obj.instance_methods(false).sort, true )
>> when CLASS_VARS then
>> obj = ObjectSpace._id2ref( iter.parent[REF].to_i )
>> initialize_vars_list( obj, iter,
>> obj.class_variables.sort, :class_eval )
>> when CONSTANTS then
>> obj = ObjectSpace._id2ref( iter.parent[REF].to_i )
>> constants = obj.constants
>> if obj.respond_to?(:superclass) && obj.superclass
>> constants = constants - obj.superclass.constants
>> end
>> initialize_vars_list( obj, iter, constants.sort, :const_get )
>> else
>> raise "don't know what to do with row of type #{iter[TYPE]}"
>> end
>> end
>>
>> path_str = iter.path.to_s + ":" + ( iter.n_children - 1 ).to_s
>> path = Gtk::TreePath.new( path_str )
>>
>> @tree.scroll_to_cell( path, nil, true, 1.0, 0 )
>> end
>>
>> def add_node( parent, object, node=nil )
>> unless node
>> node = add_row( parent, "", object, OBJECT, false )
>> add_row( node, "class", object.class, CLASS )
>> else
>> add_row( parent, "class", object.class, CLASS, true, node )
>> node = parent
>> end
>>
>> if object.is_a?( Module )
>> if object.respond_to?(:superclass) && object.superclass
>> add_row( node, "extends", object.superclass, SUPERCLASS )
>> end
>> add_row_unless_empty(
>> object.class_variables, node, "Class Variables", CLASS_VARS )
>>
>> constants = object.constants
>> if object.respond_to?(:superclass) && object.superclass
>> constants = constants - object.superclass.constants
>> end
>>
>> add_row_unless_empty( constants, node, "Constants", CONSTANTS )
>> add_row_unless_empty( object.instance_methods(false), node,
>> "Instance Methods", INSTANCE_METHODS )
>> end
>>
>> add_row_unless_empty( object.instance_variables, node,
>> "Instance Variables", INSTANCE_VARS )
>> add_row_unless_empty( object.public_methods(false), node,
>> "Public Methods", PUBLIC_METHODS )
>> add_row_unless_empty( object.protected_methods(false), node,
>> "Protected Methods", PROTECTED_METHODS )
>> add_row_unless_empty( object.private_methods(false), node,
>> "Private Methods", PRIVATE_METHODS )
>>
>> node
>> end
>>
>> def add_row_unless_empty( list, node, name, type, add_empty=true )
>> unless list.empty?
>> summary = list.sort.join( "," )
>> summary = summary[0,60] + "..." if summary.length > 63
>> add_row( node, "#{name} (#{summary})", nil, type )
>> end
>> end
>>
>> def add_row( parent, label, value, type, add_empty=true, node=nil )
>> node = @model.append( parent ) unless node
>>
>> node[ LABEL ] = label
>> node[ TYPE ] = type
>> node[ REF ] = value.object_id
>>
>> @model.append( node ) if add_empty
>>
>> node
>> end
>>
>> def initialize_methods_list( obj, iter, list, instance=false )
>> node = iter.first_child
>> list.each do |item|
>> if instance
>> method = obj.instance_method( item.to_sym )
>> else
>> method = obj.method( item.to_sym )
>> end
>> add_row iter, item + "(#{method.arity})", obj, STRING, false, node
>> node = nil
>> end
>> end
>>
>> def initialize_vars_list( obj, iter, list, message )
>> node = iter.first_child
>> list.each do |item|
>> value = obj.__send__( message, item )
>> add_row iter, "#{item}=", value, OBJECT, true, node
>> node = nil
>> end
>> end
>> end
>>
>> end
>>
>> if __FILE__ == $0
>> @obj = ObjectBrowser::Interface.new
>> @obj.display_and_wait
>> end
>>
>
>
>
> .
>


--
Jamis Buck
jgb3@email.byu.edu
http://www.jamisbuck...


4 Answers

gabriele renzi

11/22/2004 7:05:00 AM

0

Jamis Buck ha scritto:

> Having never used GTK in Windows, I have no idea how easy/hard it is to
> get ruby-gtk2 running under Windows. YMMV. YHBW.

not hard, and actually your example runs fine :)


> - Jamis
>
> P.S.: A plea to the ruby-gnome2 folks: a gemmable version would be a
> real boon. A similar plea to the RPA folks... ;)

+1

Masao Mutoh

11/22/2004 1:56:00 PM

0

Hi,

On Mon, 22 Nov 2004 11:38:36 +0900
Jamis Buck <jgb3@email.byu.edu> wrote:

> R. Mark Volkmann wrote:
> > I'm new to using gems. Can you tell me the command I need to run to get
> > ruby-gtk2 so I can run your code?
>
> Unfortunately, ruby-gtk2 is not a gem, nor is it in rpa. So you have to
> install it the "hard" way--from source. If you're on Windows, it's even
> harder: you have to install GTK2 first.
>
> GTK2: http://w...
> Ruby-GTK2 (part of Ruby-Gnome2): http://ruby-gnome2.sourc...
>
> Having never used GTK in Windows, I have no idea how easy/hard it is to
> get ruby-gtk2 running under Windows. YMMV. YHBW.

See http://ruby-gnome2.sourc...hiki.cgi?Install+Guide+for+Windows
You can install them just four steps, though it's not one click ;).

> - Jamis
>
> P.S.: A plea to the ruby-gnome2 folks: a gemmable version would be a
> real boon. A similar plea to the RPA folks... ;)

Good idea. Are there anyone to work for them ?

--
:% Masao Mutoh<mutoh@highway.ne.jp>


Mauricio Fernández

11/22/2004 3:51:00 PM

0

On Mon, Nov 22, 2004 at 10:55:35PM +0900, Masao Mutoh wrote:
> See http://ruby-gnome2.sourceforge.jp/hiki.cgi?Install+Guide+f...
> You can install them just four steps, though it's not one click ;).
>
> > - Jamis
> >
> > P.S.: A plea to the ruby-gnome2 folks: a gemmable version would be a
> > real boon. A similar plea to the RPA folks... ;)
>
> Good idea. Are there anyone to work for them ?

The RPA stuff is on the way (will take a while though).

--
Hassle-free packages for Ruby?
RPA is available from http://www.rubyar...


Masao Mutoh

11/22/2004 4:04:00 PM

0

Hi,

On Tue, 23 Nov 2004 00:51:28 +0900
Mauricio Fern__ndez <batsman.geo@yahoo.com> wrote:

> On Mon, Nov 22, 2004 at 10:55:35PM +0900, Masao Mutoh wrote:
> > See http://ruby-gnome2.sourceforge.jp/hiki.cgi?Install+Guide+f...
> > You can install them just four steps, though it's not one click ;).
> >
> > > - Jamis
> > >
> > > P.S.: A plea to the ruby-gnome2 folks: a gemmable version would be a
> > > real boon. A similar plea to the RPA folks... ;)
> >
> > Good idea. Are there anyone to work for them ?
>
> The RPA stuff is on the way (will take a while though).

Wow, Great ;).
Thanks in advance.

--
:% Masao Mutoh<mutoh@highway.ne.jp>