in reply to OO Perl: Nested classes question

This node falls below the community's threshold of quality. You may see it by logging in.

Replies are listed 'Best First'.
Re^2: OO Perl: Nested classes question
by jdporter (Paladin) on Sep 08, 2006 at 15:45 UTC
    Too verbose.
    sub condition { my $self = shift; my $condition = shift or die "missing condition"; $self->{_condition}{$condition} ||= new Condition; }
    We're building the house of the future together.
      Thanx to All... I think the solution of my problem was the usage of the hash to store new classes, which is especially elegant solution below:
      $self->{_condition}{$condition} ||= new Condition;
      Actually I did solved the problem with some Java-Collegue, who pointed my mistake, but not so elegant way (I used two methods, one for adding new class, another for setting / getting it's values).
Re^2: OO Perl: Nested classes question
by tilly (Archbishop) on Sep 08, 2006 at 15:33 UTC
    I think it is time for update 3, because that is not how Perl classes work. Perl classes work by what has been defined in the right package. By tradition you put one class per file, but Perl does nothing to enforce that tradition. (But use won't work properly unless you do that, so it is a good tradition to follow.)

    Also I note that your "preferred way to call constructors" comment is just cargo culting unless you can give some concrete reasons why that is preferred. I'm betting that you can't.

    Also what is the reason that you're afraid of using unless? (I'm not saying that you should use it, I'm just asking what your reason is.)

      But use won't work properly unless you do that, so it is a good tradition to follow.

      In which sense?

      #!/usr/bin/perl -l use strict; use warnings; use lib sub { pop eq 'Foo.pm' && do { my $mod = join "\n", (map <<".EOM", 'A'..'Z'), "1;\n"; # -------------------- package Foo::$_; sub new { print __PACKAGE__; bless [], shift; } # -------------------- .EOM open my $fh, '<', \$mod or die $!; $fh; }; }; use Foo; Foo::J->new; Foo::A->new; Foo::P->new; Foo::H->new; __END__
        Cute, but find me an instance of that being used in the wild that way.
      Also I note that your "preferred way to call constructors" comment is just cargo culting unless you can give some concrete reasons why that is preferred. I'm betting that you can't.

      That's hardly fair. Almost no one can explain every case in which indirect constructor invocation can fail badly with unintelligible error messages -- or was that the answer you wanted to hear? (It's the one I usually give.)

        I think it was fair. Repeating undigested information by rote provides fertile grounds for myth and rumor.

        Besides I'm unconvinced by your answer. I am unconvinced because it is also true that almost no one can explain every case in which direct constructor invocation can fail badly with unintelligible error messages. Here is an example:

        # We have some code, and somewhere wrote open(Foo, "> /dev/null") or die "Cannot write /dev/null: $!"; # Time passes... my $obj = Foo->new; # And elsewhere package Foo; sub new { bless {}, shift; } # ... 1;
        And yes, I know that you are in the set of "almost no one".
      Also I note that your "preferred way to call constructors" comment is just cargo culting unless you can give some concrete reasons why that is preferred.
      (of course you know this but) fear of imported subroutines is one reason ..

      # Stuff.pm package Stuff; use base 'Exporter'; @EXPORT = qw(new); sub new { print "this is exported new!\n" }
      # new.pl use Stuff; my $foo = Foo->new; # this works $foo->baz; my $bar = new Foo; # this doesn't $bar->baz; package Foo; sub new { my $class = shift; print "constructing a $class\n"; bless {}, $class; } sub baz { my $self = shift; print "hello from a ", ref $self, "\n"; }
      % perl new.pl
      constructing foo
      hello from a Foo
      this is exported new!
      Can't call method "baz" without a package or object reference at new.pl line 9.
      
      Perl classes work by what has been defined in the right package. By tradition you put one class per file, but Perl does nothing to enforce that tradition.

      Looks like I learned something new again.

      (But use won't work properly unless you do that, so it is a good tradition to follow.)

      And that's probably why I was thinking the one class per package thing is required.

      Also I note that your "preferred way to call constructors" comment is just cargo culting unless you can give some concrete reasons why that is preferred. I'm betting that you can't.

      I used to know why :) As best as I remember it had something to do with inherited constructors not working properly. (But you're right, since I can't really remember why anymore it is a cargo-cult thing now.)

      Also what is the reason that you're afraid of using unless?

      I strongly dislike the action appearing before the condition. I find it to be a lot more prone to causing confusion (for me) and decreasing readability. (And yes I know there's plenty of people who argue it does exactly the opposite.)

        I think we're now on the same page on most of this, but there is one point we're not.

        Also what is the reason that you're afraid of using unless?
        I strongly dislike the action appearing before the condition. I find it to be a lot more prone to causing confusion (for me) and decreasing readability. (And yes I know there's plenty of people who argue it does exactly the opposite.)
        This isn't what I was talking about. I asking about writing
        if (! defined $self->{_condition}{$condition}) { $self->{_condition}{$condition} = Condition->new(); }
        versus
        unless (defined $self->{_condition}{$condition}) { $self->{_condition}{$condition} = Condition->new(); }
        There are arguments both ways, I was wondering what your arguments were. (Basically my belief is that if you're going to offer advice, you should be able to back it up.)