Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Re^2: [perl6] Complex Attribute Validation and/or Triggers (good OO)

by duelafn (Parson)
on Mar 07, 2015 at 11:50 UTC ( [id://1119169]=note: print w/replies, xml ) Need Help??


in reply to Re: [perl6] Complex Attribute Validation and/or Triggers (good OO)
in thread [perl6] Complex Attribute Validation and/or Triggers

I can accept that. However, if there truly is no way of doing it with attributes, it makes me a bit sad since it makes using perl6 public attributes "dangerous". If I start a simple project using attributes and later determine that I need some additional checks or triggers that are not possible using attributes then I have to go back and munge a bunch syntax, replacing $i.lb = 6 with $i.lb(6). This would turn attributes into a "nice feature that I can't use without feeling guilty".

Good Day,
    Dean

Replies are listed 'Best First'.
Re^3: [perl6] Complex Attribute Validation and/or Triggers (anti-modular)
by tye (Sage) on Mar 08, 2015 at 07:43 UTC
    if there truly is no way of doing it with attributes, it makes me a bit sad

    My comment had nothing to do with whether or not anything is possible in Perl 6.

    it makes using perl6 public attributes "dangerous"

    Duh. Yeah, public attributes are a bad idea.

    Even if you manage to make $i.lb = 6; fatal when 4 == $i.ub, then users of your object are likely to do:

    $i.lb = 6; $i.ub = 7;

    and have it die half-way through.

    OO in the style of "a bag of attributes with wrappers around setters (types, 'before's, etc.)" is just a terrible (anti-modular) approach to OO (despite it being extremely common).

    - tye        

      I almost didn't post in this thread precisely because the initial #perl6 reaction was "what tye said" (referencing your initial just-write-a-method response). I'm pretty sure they'd say the same of this follow up, but I'll add :

      public attributes are a bad idea

      Indeed. There are no public (or even protected) attributes in Perl 6 OO, only private. Code that uses objects, and even sub, super, and trusted classes, has to go thru method accessors.

      Update Fwiw, on reviewing this thread I'm pretty sure I missed tye's point. I'm right that Perl 6 doesn't have "public attributes" using Perl 6 vocabulary. But (I think) tye meant that even public accessor methods are generally a bad idea (no matter what language one is using).

Re^3: [perl6] Complex Attribute Validation and/or Triggers (good OO)
by raiph (Deacon) on Mar 08, 2015 at 06:23 UTC
    »»» This post is about alpha status Perl 6, not rock solid Perl 5 «««

    tl;dr A) You're already using automatically generated method calls without knowing it. B) Your assignments will continue to work if you override these with your own manually written attribute accessors. C) There's more to this than meets the eye. ;)

    If one compiles this:

    class c { has $.lb }

    the compiler creates both a private read-only attribute and a public read-only accessor method. It's as if one had written:

    class c { has $!lb; #| Auto-generated if there's no explicit `lb` method: method lb { $!lb } }

    The generated `lb` accessor method provides public read-only access to the otherwise private read-only `$!lb` attribute.

    If one writes:

    class c { has $.lb is rw; } # note the `is rw`

    the compiler automatically creates a corresponding lvalue method that provides read/write access as if you had written:

    class c { has $!lb; #| Auto-generated if there's no explicit `lb` method: method lb is rw { $!lb } # note the `is rw` }

    When the compiler sees code of the form `$i.lb = 6` it calls the `lb` method and treats the result as a container to which the RHS (the `6`) is assigned. For example one could write the following bizarre but hopefully self-explanatory code:

    my $container; class c { #| `is rw` means return the container, not its value method m is rw { $container } }; my $o = c.new; $o.m = 6; say $container # prints `6`, the container's contents


    With that confusion out of the way (hopefully I haven't created more!) you may be interested in the following (edited) dialog about your Interval example use case:

    raiph    What's the intended way to create
             (the equivalent of) validating setter methods?
    jnthn    Preferably, fold the validation into the type
             (using subset types)
    raiph    will a subset type on an attribute support access to self?
    jnthn    No
             If you want an l-value-ish interface where
             you can do what you like, there's Proxy
             But an object with interesting enough invariants
             that you want to do more sophisticated things
             probably deserves an interface expressed in
             terms of meaningful method names rather
             than just getter/setter logic.
    raiph    fwiw the use case is an Interval class with
             lower/upper bounds; setters for those; and
             the invariant lower <= upper.
    jnthn    I lack context, but off-hand, Interval sounds
             to me like a value object, and so the kinda thing
             where I'd go for an immutable design.
             (And validate at construction time)
    


    Which brings me to my cryptic "more to this than meets the eye" comment at the start. There's tye's and jnthn's admonitions. And more than I was expecting of: lack of sugar; bugs; not yet implemented stuff. YMMV but, at least in the near term (this year? next?) may not...

Re^3: [perl6] Complex Attribute Validation and/or Triggers (good OO)
by AppleFritter (Vicar) on Mar 07, 2015 at 12:14 UTC

    It may help to think of constraints on attributes as being either static or dynamic (I'm just making up these terms). Those that only take into account the attribute itself and don't rely on external values are static; numbers being non-negative, strings being non-empty, that sort of thing.

    By contrast, requiring that the lower bound of an interval does not exceed its upper bound is a dynamic constraint: you can't know whether the constraint is violated without actually checking the upper bound, i.e. accessing the interval object.

    It may thus help to use public attributes only when you can be sure that all constraints are static in nature. If you need dynamic constraints, use methods so you have the language's full power at your disposal for verification.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (6)
As of 2024-04-19 12:45 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found