[Perl5-syntax] Adding Moose type checking to Method::Signatures
Buddy Burden
barefootcoder at gmail.com
Wed Mar 2 19:54:57 GMT 2011
Michael,
> The only way the invocant will be messed up is if you deliberately subvert the
> normal method call process.
>
> my $obj = A::Totally::Different::Class->new;
> $obj->Some::Class::method(@args);
>
> This is something you're highly unlikely to do by accident.
>
> There's people passing the wrong arguments by mistake, and then there's people
> deliberately passing the wrong invocant. I'm concerned with helping catch
> mistakes rather than stopping people who really want to do something crazy.
No, I definitely agree with that. I don't want to stop anyone doing
anything crazy on purpose either; that crazy person could well be me.
:D I just want there to be a clear way to distinguish between class
methods and object methods ... I guess that's the only thing I really
care about. And, as you say, type-checking isn't the only way (and
possibly not the best way) to do that.
>>> Perl 6 has the "method ^foo" syntax.
>>> http://perlcabal.org/syn/S12.html#Class_methods
>>
>> Hunh. I'm not fond of that synxtax _personally_, but if it's going to
>> be official P6 syntax, I suppose we could parse it. Seems trivial
>> enough to do so.
>
> I'm not fond of it either. And it's tied up with the metaclass object, so
> it's not clear how useful it is in Perl 5.
Yeah, let's just table that for now. :)
> Sorry, I'm using up all my brilliant thoughts on Test::Builder2 and my current
> client's $work.
Fair enough. If something brilliant strikes me while I'm in there
hacking, I'll be sure to share. ;->
>> "is" checks inheritance, whereas "does" checks role composition. So
>> they're not quite synonyms.
>
> You sure? That's isa and does in Moose... but the MXMS traits are unrelated
> to types and roles, no? You are talking about this:
>
> Traits
> method foo (Affe $bar does trait)
> method foo (Affe $bar is trait)
>
> The only currently supported trait is "coerce", which will attempt to
> coerce the value provided if it doesn't satisfy the requirements of the
> type constraint.
>
> or something else? From the above, I read does and is as synonyms for
> applying traits.
Hunh. You're right ... _as MXMS implements it_, "does" is just a
synonym for "is", which makes it rather useless. That's not what I
was talking about then. :) I believe the way P6 uses it (and
certainly the way that *I* would want to use it) is to check roles.
After all, the whole point of the role is to have a more flexible
solution for problems that are currently solved with inheritance.
And, as chromatic so eloquently put in his blog essays on roles,
sometimes duck typing just doesn't cut it.(*) So if I'm using a role
to guarantee that a class conforms to a given interface, don't I need
a way to check that?
method foo ($bar does Executable)
{
# now I know I can do this
$bar->exec();
}
>>> You're right that if MS doesn't implement syntax, it should die or warn rather
>>> than silently ignore it.
>>
>> Okay, so instead of having those methods in the base class be empty,
>> just have them spit out warnings? Yeah, I could get behind that.
>> (Errors seem like overkill, but warnings are definitely appropriate:
>> Warning! Your syntax isn't really doing anything here; sorry about
>> that.)
>
> ...I'm split. A warning at least lets the code work... but the only way to
> silence the warning is to either remove the type check or fix your types... so
> it might as well be an error...
>
> Since Method::Signatures is lexical, I don't see how you'd write code with a
> feature if you didn't intend to use it. I'd go with an error. At least you
> can easily trap an error.
Actually the way I've done it thus far (I've officially started the
hacking; woohoo!) is like so:
use Method::Signatures { warn => 0 };
and that turns the warnings off. Or we could come up with a different
(or additional) interface if you like:
use Method::Signatures qw<:NOWARN>;
perhaps. I just kept things so I'd have to fiddle with import() as
little as possible.
What I really wanted was something like:
no warnings 'reserved'; # or other appropriate category
but I couldn't get that to work, so I went with the above. But it's
simple enough to change if you have a preference.
> Yeah. You're a committer now so there's no point in forking and merging pull
> requests is more work for me (or you).
>
> As for branching or working on master, use your head. Keep master working.
> New features or scary bug fixes go into a branch. When in doubt: branch.
>
> But by cloning you're always working in your own local branch. Nothing is
> committed until you push. So often you can just work on master in your own
> clone, do a bunch of commits, and then push when it's ready. And as long as
> you haven't pushed you can always turn your local commits to master into a branch.
Okay, cool. That's what I'll do then. Seeing as how I just changed
the way invocant parsing works (it was conflicting with a class type
on the first parameter), I'd say this work qualifies as both new
feature _and_ scary bug fix. :-D So I'll turn my clone into a branch
and we'll go from there.
Thanks for all the guidance!
-- Buddy
(*) http://www.modernperlbooks.com/mt/2009/05/perl-roles-versus-duck-typing.html
More information about the Perl5-syntax
mailing list