Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

Re^3: MooseX obscure error and importance of Unit Testing

by chromatic (Archbishop)
on Aug 16, 2012 at 05:12 UTC ( #987695=note: print w/ replies, xml ) Need Help??


in reply to Re^2: MooseX obscure error and importance of Unit Testing
in thread MooseX obscure error and importance of Unit Testing

Do you know a more reliable solution, other than constructing optrees by hand?


Comment on Re^3: MooseX obscure error and importance of Unit Testing
Re^4: MooseX obscure error and importance of Unit Testing (tools)
by tye (Cardinal) on Aug 16, 2012 at 05:22 UTC

    I prefer: 1) Don't use tools that make subroutines having the same names as classes. 2) Don't use tools (like old base.pm) that silently ignore failures when you try to require a module.

    But since I find Moose so strongly pushes toward bad class design (and MooseX::Declare leads to obscure errors and days wasted debugging), not using them is no hardship for me anyway. :)

    - tye        

      If you don't like silent failures, then you should be a big fan of ClassName::->new. With warnings enabled it will emit a compile-time warning if the ClassName package hasn't been loaded.

      Update: also according to my benchmarking (under Perl 5.16.0), ClassName::->new runs faster than ClassName->new. 'ClassName'->new is somewhere in between; ClassName->new is the slowest.

      use Benchmark; sub new { bless \@_, $_[0] } timethese(100_000, { bareword => sub { eval q{ main->new } }, quoted => sub { eval q{ 'main'->new } }, colons => sub { eval q{ main::->new } }, });

      Most of the penalty appears to be at compile-time, but the following illustrates that there's a small performance penalty at runtime too:

      use Benchmark; sub new { bless \@_, $_[0] } timethese(1_000_000, { bareword => sub { main->new }, quoted => sub { 'main'->new }, colons => sub { main::->new }, });

      So given that ClassName::->new is unambiguous, faster and can provide helpful warning messages when lexical warnings are enabled, what possible argument (other than force of habit) can there be for using ClassName->new? In cases where the warnings need to be suppressed (e.g. calling a class method on a class loaded at run-time), then 'ClassName'->new can be used, because that is also unambiguous, and also faster than ClassName->new.

      Update 2: further testing with the runtime-only tests seems to show that the quoted version may actually be fastest at run time. The bareword version is still slowest though. The version with the colons wins hands-down at compile-time. Either way, the speed difference is minor - the primary argument against the bareword version is its ambiguity.

      perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'

        When I first saw ClassName::->new() proposed as a way to prevent ambiguous interpretation of ClassName->new(), it was shortly revealed that it didn't actually result in unambiguous parsing. It sounds like Perl's parsing may have been changed to improve that.

        I'd actually rather more improvements be done so ClassName->new() is unambiguous [or at least generates a warning when it isn't unambiguously 'ClassName'->new()]. I'd much prefer to have to actually write (the first "()" in) Function()->new() when that is what I want. That turned out to be the sane thing for both $hash{BareWord} and BareWord => $value, despite it taking years to realize that.

        For now, I'm not just yet going to run off and adopt the new fad considering the history of the many things in Perl that I've been told I should just stop using the old alternatives to, only to later find the new "must use" feature getting seriously down-graded, often out-right deprecated: v strings, pseudo hashes, base.pm, version.pm, Switch.pm, LVALUE subs, inside-out objects, source filters (actually, that last one became unpopular almost as soon as it became possible).

        Then there are the things that I've already realized serious problems with that the broader community may eventually clue in to: using inheritance for things like Exporter / AutoLoader / DynaLoader, 'use warnings' in modules or in test suites, given/when, 'smart' match (it smarts!), { ... redo ... }, inheritance, my $x = shift, objects as glorified hashes, Moose, MooseX::Declare (wait, I already said "source filters"). I'm sure I'm leaving a few out. :)

        But I'll keep it in mind. I appreciate the reminder of this potential pit-fall and the note about the compile-time warning.

        - tye        

      What makes you feel Moose pushes strongly toward bad class design?

      Three thousand years of beautiful tradition, from Moses to Sandy Koufax, you're god damn right I'm living in the fucking past

        Public accessors, for one.

        I disagree slightly with tye that Moose forces them on you, but any OO code which spends a lot of time setting (or Larry help us all, even getting) attribute values from outside the object is questionable.

        Good objects let you tell them what to do.

        What makes you feel Moose pushes strongly toward bad class design?

        :) tye say the documentation and implementation

        The documentation (esp examples) encourage designing classes in terms of attributes not in terms of interfaces (tye say good design is interface first, then internal details like attributes)

        The implementation , is based around attributes, so if you don't generate accessors then you can't make use of many "roles".

        see How Large Does Your Project Have To Be to Justify Using Moose?, read tye say this

Re^4: MooseX obscure error and importance of Unit Testing
by Anonymous Monk on Aug 16, 2012 at 07:15 UTC

    Do you know a more reliable solution, other than constructing optrees by hand?

    I don't need one, I manage to avoid writing subroutines that clash with classes, pretty much the same way most of CPAN and everyone else seems to, fairly easily :)

    Although this might be a candidate :) subs::auto - Read barewords as subroutine names.

    This pragma lexically enables the parsing of any bareword as a subroutine name, except those which corresponds to an entry in %INC (expected to be class names) or whose symbol table entry has an IO slot (expected to be filehandles).

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://987695]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others rifling through the Monastery: (12)
As of 2014-07-22 12:14 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (112 votes), past polls