On Mon, Jul 04, 2005 at 05:33:37PM +0200, Ingo Blechschmidt wrote:
: Hi,
: 
: .assuming is non-mutating on Code objects:
: 
:   my $subref         = &some_sub;
:   my $assumed_subref = $subref.assuming(:foo<bar>);
:   $subref =:= &some_sub;    # true, $subref did not change

I think .assuming implies a copy of your view of the subroutine, even
if internally it's implemented with the same sub.  (But it needn't be.)
So =:= would be false after .assuming.  And .=assuming would probably
be illegal, though if you succeeded it would change *everyone's*
view of that sub's signature, which seems somewhat antisocial.

Another way to say it is that if you change something's interface,
you really ought to change its identity.

: Quoting S06:
: > The result of a use statement is a (compile-time) object that also
: > has an .assuming method, allowing the user to bind parameters in
: > all the module's subroutines/methods/etc. simultaneously:
: > 
: >     (use IO::Logging).assuming(logfile => ".log");
: 
: So, .assuming mutates the Module/whatever objects. And, given the
: general trend to non-mutating methods (.wrap, .assuming), and the
: easiness of the .= operator, I'd propose making this kind of .assuming
: non-mutating, too:
: 
:   (use IO::Logging).assuming(logfile => ".log");   # noop
:   (use IO::Logging).=assuming(logfile => ".log");  # works
: 
: Opinions?

I don't think that's how it works.  We almost never want to mutate
a module in place, and if we do, it's probably a job for .=wrap, not
.assuming.  They're really there for different reasons: .assuming
is for changing the interface without changing the implementation,
whereas .wrap is for changing the implementation without changing
the interface.

Perl 6 always aliases a module's short name to a longer name, and the
main reason for that is binding to different versions without having to
respecify the version at every mention of the module name.  However,
another reason is so that we can alias IO::Logging to an anonymous
"view" class, so that we don't have to respecify the default arguments.
We could conceivably do that just by distributing .assuming to all the
routines and methods involved (presuming we can know them in advance),
but there is probably some good in keeping track of the indirection
at the module name level.

In any event, it makes little sense to mutate a module or class in
place unless you're heavily into AOP (and even there you're trying to
preserve the interface).  If you're going to change the interface it's
usually better to allow different lexical scopes to have different
views to avoid problems with magical action at a distance.

Larry

Reply via email to