Mark A. Biggar skribis 2005-04-23 10:55 (-0700):
> After some further thought (and a phone talk with Larry), I now think
> that all of these counted-level solutions (even my proposal of _2.foo(),
> etc.) are a bad idea.
In that case, why even have OUTER::?
I agree, though, and have always found this, that using the full name
(binding one if it doesn't have one already) is the better solution.
given returns_object() -> $foo {
when SomeClass { ... }
}
I think we all agree that smart match (implied by when) should work on
$_. The following is consistent with the above:
method ($foo: @bar) {
when SomeClass { ... }
}
Only the first line changes, and everything still works as expected.
The same would work very well for method calls:
method ($foo: @bar) {
.method;
}
I would expect that if we change the first line back (less academically,
copied and pasted the code elsewhere), it would still work on the same
thing.
given returns_object -> $foo {
.method;
}
The block passed to given aliases the first argument to $_. Methods
should do the same. And I really beleave that using a : to separate
instead of , does not make the invocant any less the first argument.
> They have a similar problems to constructs like "next 5;" meaning jump
> to the next iteration of the loop 5 level out.
Yes, that's ugly.
> Any time you refactor you code and change levels, they break in a
> subtle and very hard to debug way, causing mysterious errors.
Same thing for having one thing default to $_ and another to $self, in a
way. If everything defaults to $_, which may or may not be the same
thing as $self, things become more predictable, and you can when
refactoring just copy the body of a loop to a new method without
breaking it.
> Just like the current Perl construct of "labeled loops" so that you
> can talk about the target loop explicitly, the proper solution for
> up-level access to $OUTER::OUTER::...::OUTER::_ is to create a named
> binding like "$uplevel_topic := $_;" at that upper level and then use
> that to refer to it at lower levels.
Indeed. Fortunately, many built in constructs involving blocks that get
arguments already set up that binding for you.
> Beside is ".......foo();" seven of eight levels up?
A rather irrelevant question, IMHO. It is as irrelevant as the similar
"Is 5521243 approximately .5 million or 5.5 million?", because just as
you can write 5_521_243 to make the number more clear, you could write
... ... .foo();
to show it's 7 dots.
> Any other way than explicit naming is madness; leading to unreadable
> and unmaintainable code.
Not if implict naming (completely implicit, that is, so without any
indication of level even) is consistent in what it means. Currently,
things default to $_ in almost every place where a value is needed but
left out. I'd hate to see that change to some other variable for only a
portion of the operations now defaulting to $_.
Automatic binding of the invocant as $_ and the possibility to provide
your own name for the thing (either by specifying it in the signature or
by explicitly using the := operator) makes that .method defaulting to
working on $_ is not a problem.
A method's block shouldn't be too different from a given's block, or any
other closure for that matter. They should both topicalize using the
same semantics, IMO.
Juerd
--
http://convolution.nl/maak_juerd_blij.html
http://convolution.nl/make_juerd_happy.html
http://convolution.nl/gajigu_juerd_n.html