Hello,
I am forking this off the "Perl 6 OO and bless" thread since that
seems to have gotten bogged down in what it all means to Perl 5
interoperability. This was not really my intent with the original
thread, but I think it is still a fruitful discussion so I will re-
make my original point here with more detail.
First I need to establish a few things on which my argument rests.
So, S02 says that Perl 6 is an OO engine. Which means that a hash is
not a literal "thing" but an instance of the class ^Hash. This means
that a hash now has methods which can be called on it, and inherits
from ^Object.
Because @Larry does not want the OO-ness of the language to get in
the way of doing ones job, all the methods of ^Hash are either
transformed into pseudo-built-in-functions using macros (see the Hash/
delete/UnaryForm part of S29), or would be aliased as multi-subs
which dispatch using MMD.
Take this (very simplified) pseduo-code for &exists:
method Hash::exists (^Hash %h: Any $label) return Bool {
%h{$label} ?? bool::true !! bool::false
}
And lets assume that a macro has been written to make it callable in
the built-in function style which will transform this:
exists %h{'foo'}
Into this:
%h.exists('foo');
Now, what happens when we bless a hash.
class Foo {
method new ($class: %params) {
$class.bless(%params);
}
method bar ($self:) { ... }
}
The result of Foo.new is an instance of ^Foo. In Perl 5, the hash
would be tagged with the package name it was blessed into, but it
would still be a hash reference, only now you could also call methods
on it. This *won't* work the same in Perl 6 though. This is because,
what is blessed is not a literal "hash", but an instance of ^Hash. If
we follow the Perl 5 logic, then we can now call methods on this
blessed hash, but we cannot use the hash built-in functions since
they are just macro transformations into method calls. Take this code
example:
my $foo = Foo.new({ one => 1, two => 2 });
exists $foo{'one'}; # this will not work
The reason this the above code will not work is because "exists $foo
{'one'}" will be transformed by the macro to "$foo.exists('one')",
which will fail since no &Foo::exists exists. Even if we tried to do
this (and assuming the macro would DWIM):
Hash::exists $foo{'one'};
This would fail anyway since Hash::exists is expecting a ^Hash
instance as it's invocant arg, and not a ^Foo instance, so it would
fail on the parameter/argument type check.
I think this is a deep problem with how &bless works, how the
container types work, and maybe even how our MMD system works. I
think we need to have a well reasoned solution to this which is
devoid of any magic hand waving.
Thanks,
Stevan