Re: OO style: Placement of "new"
by broquaint (Abbot) on Apr 07, 2003 at 13:26 UTC
|
Is there a rationale or even benefit behind this syntax, or is it just syntactic sugar for the $obj->some_method notation?
Indeed, your second code example is demonstrating 'indirect method invocation' by way of using an 'indirect object', which is syntactic sugar for all the C++ (and the like) types. For more info on the subject do a search for 'indirect object' and specifically see tye's node on why it's not generally a great idea.
HTH
_________ broquaint
| [reply] |
Re: OO style: Placement of "new"
by Abigail-II (Bishop) on Apr 07, 2003 at 13:28 UTC
|
Don't use syntax 2 (also known as "indirect object method").
For reasons why you shouldn't use it, read the section named
Indirect Object Syntax in the perlobj
manual page.
Abigail | [reply] |
|
|
I fail to see any actual prohibition in that section, at least, not on class methods. To be honest, most of what's said in that section doesn't even belong in there. The only warning I actually spot against it there, is on that "parens around all parameters" thing:
new Critter ('Bam' x 2), 1.4, 45
However, that's precisely the same problem you get when you do
print ('Bam' x 2), 1.4, 45;
so that's nothing new.
OTOH, the one problem I did notice with this "indirect object method", is that it doesn't work with perl's built-in keywords — and likely other predefined subs as well, so the next doesn't call the method "open" in the class "ReadFile":
my $handle = open ReadFile($file);
Instead, you have to use
my $handle = ReadFile->open($file);
I guess that falls under "the same ambiguity as ordinary list operators", in perlobj. | [reply] [d/l] [select] |
|
|
The problem isn't precedence. The problem isn't keywords
either. The problem is that
new Foo;
might call either of
&new ('Foo'); # Calling new in the current package
or
Foo -> new (); # Calling new in Foo, or a parent class
And there are a bunch of cases that decide which one it will be.
And no, Perl doesn't like "prohibitions". You are free to do
whatever you fancy. But the documentation does give advices
on how not to get hurt.
Abigail | [reply] [d/l] [select] |
|
|
A blanket prohibition like this is as unwarranted as forbidding the use of $_ on the assertion that it is obfuscation. I use the indirect syntax for constructor calls almost exclusively and I have never encountered the problems described in perlobj.
crenz, use whatever form suits your tastes or the coding style your project settles upon, and allow the constraints of a particular situation to guide your selection of syntax.
"The dead do not recognize context" -- Kai, Lexx
| [reply] [d/l] |
|
|
Well, maybe you haven't, but that doesn't mean nobody hasn't, because I have. So it happens in real code.
Don't use IO notation. It was an interesting experiment, but it failed.
-- Randal L. Schwartz, Perl hacker
Be sure to read my standard disclaimer if this is a reply.
| [reply] |
|
|
|
|
|
Re: OO style: Placement of "new"
by dws (Chancellor) on Apr 08, 2003 at 04:44 UTC
|
package Foo;
sub new {
print "Foo\n";
bless {}
}
package Bar;
sub new {
print "Bar\n";
bless {}
}
sub addFoo {
my $self = shift;
$self->{Foo} = new Foo(); # which new gets invoked?
}
package main;
my $bar = new Bar();
$bar->addFoo(); # if there's a bug, this should tickle it
Anything that fails to print "Foo" constitutes failure.
| [reply] [d/l] |
|
|
> perl indobj.pl
Bar
Undefined subroutine &Bar::Foo called at indobj.pl line 10.
What did I do? I simply moved package Foo to be after package Bar. That way Perl doesn't know that Foo is a package name when it compiles the line of code containing new Foo().
- tye
| [reply] [d/l] [select] |
|
|
I simply moved package Foo to be after package Bar. That way Perl doesn't know that Foo is a package name ...
So as long as Perl knows that the target is package name (i.e., if you've gotten your uses and requires right, and haven't made a typo in the name), everything works as expected. Otherwise, you have a slightly harder time debugging. Is that about it?
| [reply] |
|
|
A reply falls below the community's threshold of quality. You may see it by logging in.
|
Re: OO style: Placement of "new"
by crenz (Priest) on Apr 07, 2003 at 15:07 UTC
|
Thanks, broquaint and Abigail-II. The arguments in perlobj are definitely convincing. After reading tye's post, I think I'll not only continue to use #1, but also switch to HANDLE->print etc. in future.
| [reply] [d/l] |
Re: OO style: Placement of "new"
by derby (Abbot) on Apr 07, 2003 at 16:08 UTC
|
it seems that I can just use any method name
Which is true for case #1 also. There is nothing special about new, it's
only by convention that we use it. Your constructor method can be named
anything (literally, "anything"). It's just the wrath of downstream programmers that prevent you from doing so.
And I prefer case #1 for all the reasons all ready pointed out about indirect
invocation.
-derby | [reply] |
Re: OO style: Placement of "new"
by Anonymous Monk on Apr 07, 2003 at 19:29 UTC
|
I personally like code that "reads" like natural language, and I've seen comments by Larry that he does also. I can surely read the following:
my $object = new Thingy;
print $log "It works!\n" if $object->is_valid();
However, the alternative just doesn't read as nicely:
my $object = Thingy->new;
if ($obj->is_valid()) {
$log->print("It works!\n");
}
I do C++, but that's not why I prefer the "new class()" form. It just sounds more like the spoken word. Heck, if I were to slavishly follow C++ syntax, I'd never use the followup 'if' form. | [reply] [d/l] [select] |
|
|
This is not completely indirect object syntax:
print $log "It works!\n" if $object->is_valid();
You would instead write:
print $log "It works!\n" if is_valid $object;
Your second snippet would likewise be:
$log->print( "It works!\n" ) if $obj->is_valid();
I fail to see how that is less appealing.
| [reply] [d/l] [select] |
Re: OO style: Placement of "new"
by crenz (Priest) on May 01, 2003 at 21:47 UTC
|
| [reply] |