It always causes problems.
$ perl -MO=Deparse -e 'package Container;What you meant, perhaps, was
sub new { shift->BUILD }
sub BUILD { my $contained = new Contained() }'
package Container;
sub new {
shift(@_)->BUILD;
}
sub BUILD {
my $contained = new(Contained());
}
-e syntax OK
$ perl -MO=Deparse -e 'package Container;Basically, indirect notation breaks any time you're actually writing an object class. If you start indirectly invoking constructors (likely), you'll accidentally hit your own. Any time you go adding a new method to your own class - bang; you've just broken any indirect calls to that named method on any other object you'd be using. That sounds excessively fragile to me. Code that used to mean one thing suddenly means a different thing when you add seemingly-unrelated code in another place. Fragile breakage by action-at-a-distance. It even depends on the order of the source code:
sub new { shift->BUILD }
sub BUILD { my $contained = Contained->new() }'
package Container;
sub new {
shift(@_)->BUILD;
}
sub BUILD {
my $contained = 'Contained'->new;
}
-e syntax OK
$ perl -MO=Deparse -e 'package Container;And given probably most of the time you're writing code, you're writing objects, right? Even if the function you're writing currently isn't in an object class, it probably uses objects. Maybe one day you'll decide that function is useful in an object, so you'll copypaste that code elsewhere. This probably means most of your code ought not use indirect notation. If already most of it isn't using it, just get out of the habit NOW, before it is too late, and pretend that indirect notation does not exist at all. You'll save yourself a lot of pain later on.
sub BUILD { my $contained = new Contained() }
sub new { shift->BUILD }'
package Container;
sub BUILD {
my $contained = 'Contained'->new;
}
sub new {
shift(@_)->BUILD;
}
-e syntax OK
Very nice example of why it should never be used. Hopefully you can convince the original guy who wrote the pro-indirect notation post.
ReplyDelete