Re: the proper way to do inheritance



Quoting muppet <scott asofyet org>:
<snip>
not just the type system, but features that rely on the type system.
if you want to have your main widget be a GtkNotebook but also have 
a signal like "config_changed" or "doohickey_frobnicated", or if you 
want to have new object properties that could be seen and used by other
code, you need to register your subtype.
</snip>

<snip>
[1] there are many situations in which there are perfectly easy and
equivalent ways to do things with normal perl techniques and using
the signal/callback mechanism.  it's down to preference, really.  
i've found that signals/callbacks and object properties are really
sweet once you figure out how to use them effectively, and they take
care of a whole slew of OO abstraction scope issues that used to plague
me (if you can hook a signal to this event, then class A never needs to
know anything about class B, which needs to hook into that interaction;
listable, typesafe properties allow you to save object configuration 
without knowing anything about that object).  using Glib for the signals 
makes a lot of sense because it already handles the callback queuing 
you'd have to reimplement in perl.  all that said, i use the subclasses 
more for specialized non-widgets than i do for widgets.
</snip>

Thanks, that was what I was looking for.  But just to make certain I understand
let me give an example of how using Glib could help me.  First a little
background: I have a main window that holds a Gtk2::Notebook that holds
(possibly) many GnomeSQLEditor::Editor objects.  Each tab in this notebook holds
a label with the name of the file being edited.  When the user changes the file
I want to mark the tab with an asterisk (*) and enable the save button.  When
the user saves I want to remove the asterisk and disable the save button. 
Currently I am registering an idle function everytime I create a new
GnomeSQLEditor::Editor object to check if the object->is_dirty and adding the
asterisk (and enabling the save button) if it is.  But if I were to use Glib to
do the inheritance I could create a signal "dirty" or "has_changed" that would
be caught (instead of using the Idle function).

pacakge GnomeSQLEditor;

        sub new_editor {
                my ($self, $tab, $text) = @_;
                my $editor = GnomeSQLEditor::Editor->new($text);
                $editor->show_all;

                $tab = "new file" unless defined $tab;

                $self->{nb}->append_page(
                        $editor, Gtk2::Label->new($tab)
                );

                my $idle = Glib::Idle->add(
                        sub {
                                if ($editor->is_dirty) {
                                        my $nb   = $self->{nb};
                                        my $tab  = $nb->get_tab_label($editor);
                                        my $file = $tab->get_text;
                                        #FIXME: what if the filename ends with *
                                        #FIXME: '*' should be replaced with 
                                        #       user defined text so that 
                                        #       users who have a hard time
                                        #       seeing can use the string
                                        #       ' has changed' instead.
                                        if ($file !~ /\*$/) {
                                                $tab->set_text("$file*");
                                        }
                                }
                                return 1;
                        }
                );
                $self->{nb}->get_nth_page(
                        $self->{nb}->page_num($editor)
                )->{idle} = $idle;
                $self->{nb}->show_all;
        }

could become

pacakge GnomeSQLEditor;

        sub new_editor {
                my ($self, $tab, $text) = @_;
                my $editor = GnomeSQLEditor::Editor->new($text);
                $editor->show_all;

                $tab = "new file" unless defined $tab;

                $self->{nb}->append_page(
                        $editor, Gtk2::Label->new($tab)
                );

                $editor->signal_connect(
                        'dirty',
                        sub {
                                my $nb   = $self->{nb};
                                my $tab  = $nb->get_tab_label($editor);
                                my $file = $tab->get_text;
                                #FIXME: what if the filename ends with *
                                #FIXME: '*' should be replaced with 
                                #       user defined text so that 
                                #       users who have a hard time
                                #       seeing can use the string
                                #       ' has changed' instead.
                                if ($file !~ /\*$/) {
                                        $tab->set_text("$file*");
                                }
                                $self->{save}->set_sensitive;
                                return 1;
                        }
                );
                $self->{nb}->show_all;
        }

A savings of 7 lines[1] and it is more efficient than have tons of idle
functions being called.

[1]
Later in the code there are two more lines in the close_tab() method that are no
longer needed:
my $page    = $nb->get_nth_page($pagenum);
G::Source->remove($page->{idle}); 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]