Jaap Karssenberg <> wrote in comp.lang.perl.misc:
> On 16 Jul 2004 16:57:21 GMT Anno Siegel wrote:
> : First off, it's thin ice that it works at all (if you know what I
> : mean). In sub Race::Hose, "Race::Horse->new..." is ambiguous syntax.
> : What is left of the arrow can be any expression, so Perl would be in
> : its rights to read it as "Race::Horse()->new..." and plunge into deep
> : recursion. It Does What I Mean, but I don't think the feature is
> : documented. I don't think it is likely to go away. That would break
> : old code.
>
> I think you can be pretty sure that in the "Race::Horse->new" syntax
> "Race::Horse" is considered a class name in any current and future
> version of perl5. It is not documented explicitly AFAIK but it is used
> as in example code in several perl manpages.
It is also not true, if, at compile-time, Race::Horse is defined as
a sub. Example:
package Race::Horse;
sub new { bless {}, shift }
package Mickey::Mouse;
sub new { bless {}, shift }
my $x = Race::Horse->new; # swap
sub Race::Horse { 'Mickey::Mouse' } # swap
print ref $x, "\n";
This prints "Race::Horse", so the bare Race::Horse has been parsed as
Race::Horse a class name, as you say. But swap the indicated lines,
and it prints "Mickey::Mouse", so now it has been parsed as Race::Horse().
So the sub takes precedence, if defined at compile time. In
sub Race::Horse { Race::Horse->new( @_) }
the sub Race::Horse comes uncomfortably close to being defined at
compile time. Other ways of using a sub name inside a sub do result
in recursion, and that's the point I'm slightly worried about.
> : Another problem is name space violation. Race::Horse defines a sub
> : in package Race, where it has no business defining things. Of course,
> : there is no rule that explicitly forbids it, but it might be
> : considered poor (even rude) style. Actual collisions are improbable,
> : however. If package Race contains subs, their names are likely to be
> : lower case.
>
> For this reason I would advise against using this construct in modules
> that are intended for CPAN. At the very least check the existence of the
> sub before defining you own. But thats no real insurance.
>
> *Race::Horse = sub { # define constructor if sub doesn't allready exist
> ... code ...
> } unless *Race::Horse{CODE} ;
Ohh... much too clever for its own good, I think

It has quite some
surprise potential. If needed, I'd add a use-time option to switch it
off explicitly.
On the other hand, there is an ill-defined, but distinct, notion of
public and private name space on CPAN. As long as I'm in "my" name
space, I'll feel free to define what I please. Then again, I *am*
thinking of things like Music::Wurlitzer, where Music is an established
piece of public name space. I guess it should be optional in such
cases.
Anno