Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Moo uses code like this to add an attribute to a class:

has taste => (is => 'ro',);

That's too much typing for lazy people. So applying the standard rules: 'parentheses don't really do anything so you can delete them', 'fat commas are really just commas', leads to this:

has 'taste', 'is', 'ro';

Well there's no point typing in that comma separated list is there? Why not use qw? This works:

has qw/weight is rw default 100/;

MooseX::MungeHas allows has to haz defaults:

use MooseX::MungeHas 'is_rw'; has foo => ();

Using the 'standard rules' this becomes:

has 'foo'; # works okay

But then to create a read-only attribute, it needs to be specified:

 has roattr => (is => 'ro');

Is there a way to make hasro and hasrw functions to add attributes? Maybe there's a module that does this and i just haven't found it yet?

hasrw 'weight'; # read-write hasro 'roattr'; # read-only

Then if somebody was verrry lazy, they can easily define their classes without having to type a bunch of parentheses, fat commas, and typing in 'is' over and over again. Obviously this wouldn't be suitable for all uses.

Replies are listed 'Best First'.
Re: Extra-lazy object oriented programming
by tobyink (Canon) on Sep 08, 2014 at 21:49 UTC

    You might like this:

    package Foo { use Moo; has [qw/ foo bar baz /], is => "ro"; has [qw/ quuux xyzzy /], is => "rw"; }

    Also take a look at Moose::Tiny which could easily be ported to Moo.

      Thanks Toby. The lists of names is nice, but then they don't have defaults. Which would mean the constructors would have to hold the default values. I'd rather the defaults were in the definition.

      Moose::Tiny and Object::Tiny only do read-only, so they won't work.

      Something like this might work:

        If want defaults:

        use Moo; has [qw/ foo bar baz /], is => "lazy", builder => 1; sub _build_foo { [] } sub _build_bar { {} } sub _build_baz { 42 }
Re: Extra-lazy object oriented programming
by BrowserUk (Patriarch) on Sep 08, 2014 at 21:35 UTC
    Is there a way to make hasro and hasrw functions to add attributes?

    I cannot answer your question, but I do wonder why it has to be so verbose :)

    Why not just:

    rw 'weight'; ro 'dob';

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Extra-lazy object oriented programming
by davido (Cardinal) on Sep 08, 2014 at 23:25 UTC

    I think that if the point is to reduce typing, such things can be taken to an extreme that jeopardizes readability. People are accustomed to seeing the Moo(se)?y way of doing things. But you could always go to this extreme.....:

    package Foo; use Moo; for my $access ( qw/ro rw/ ) { no strict 'refs'; *{'_has'.$access} = sub { has shift, 'is', $access, @_ } } _hasro([qw/ foo bar baz /]); _hasrw([qw/ quuux xyzzy /]); package main; print Foo->new(qw/foo 1 bar 2 baz 3 quuuz 4 xyzzy 5/)->xyzzy, "\n";

    Smells bad to me though, and you still have parens..

    If you move away from generating the subroutines (which means introducing "repeating yourself"), you can eliminate the parens around the sub calls.


    Dave

      Maybe it's better to add the functions to Moo.pm. So I copied Moo.pm to Moox.pm and put it in the lib directory. Then changed "package Moo;" to "package Moox;". And then added a few functions after 'has': (with apologies to Matt S. Trout)

      Then other code can use it like this:

Re: Extra-lazy object oriented programming
by Laurent_R (Canon) on Sep 08, 2014 at 22:10 UTC
    If you are serious about being lazy, then you should probably forget about OO programming. Use a functional programming model, pipe-line programming, standard imperative/procedural programming or whatever other model you like, but not OO programming.

    Just kidding, of course, but I think there is quite a bit of truth to it.

Re: Extra-lazy object oriented programming
by ysth (Canon) on Sep 08, 2014 at 21:32 UTC

    Isn't that weight's default '100' now, not 100?

    A math joke: r = | |csc(θ)|+|sec(θ)| |-| |csc(θ)|-|sec(θ)| |
      It is, but it doesn't matter. It'll get converted to a number when you do some arithmetic on it.
Re: Extra-lazy object oriented programming
by tobyink (Canon) on Sep 09, 2014 at 10:46 UTC

    Your wish is my command...

    use v5.14; package Foo { use Moo; use MooseX::MungeHas 0.007 { hasro => ["is_ro"], hasrw => ["is_rw"] + }; hasro "foo"; hasrw "bar" => sub { "this is a very lazy builder" }; } my $f = Foo->new(foo => 1); say $f->foo; # "1" say $f->bar; # "this is a very lazy builder" $f->bar(2); # it's an rw attribute say $f->bar; # "2" $f->foo(2); # it's an ro attribute, dies
Re: Extra-lazy object oriented programming
by Anonymous Monk on Sep 09, 2014 at 07:33 UTC

    Here's a version using Moose::Exporter.

Re: Extra-lazy object oriented programming
by locked_user sundialsvc4 (Abbot) on Sep 09, 2014 at 10:34 UTC

    Sometimes, “laziness is not a virtue.”   If your fingers tire from “all that typing,” buy a new set of fingers.   The point – the whole point, really – is to write code that is both abundantly-clear and readily maintainable by everyone else in your shop.   Doing something that is obtuse, just to save a little typing, is not virtuous.