Perl 6 (Timo),

In terms of new() uses… I’ve seen a clever use of new() that goes beyond 
turning ‘positionals’ into ‘named’ in 
https://github.com/retupmoca/P6-Net-SMTP/blob/master/lib/Net/SMTP.pm6.  It 
wraps methods for debugging.  Pretty great, imo.

In terms of this thread’s subject…  I am coming from a SysAdmin orientation, 
where I implement large software suites with enough options to choke a pig.  
I’m writing auto-deployment scripts that manage the trickier aspects of 
installation & configuration.  Also some Perl 6 apps supporting the products.

My primary desire is to specify defaults with ‘has’, which I consider concise, 
convenient, easy to operate, and a great place to standardize specifying 
attribute defaults.  Then, while still in OC, have an opportunity to calculate 
better attribute values before returning up the call stack to new() – all 
without having to manage traits & defaults manually.  Many of my classes simply 
want to read a system command/file and provide an interface with accessors.  
new() and its accompanying stack needs to slurp in all of the source 
information, resulting in well-loaded attributes with accessors ready to answer 
questions.  If I can get new() to load up all attributes, then there will be no 
need for a clunky new()->my-more-complete-init() in my classes.  Hundreds of 
classes…

Perl 6 provides a comprehensive simplest-case for Object Construction (OC) when 
only attributes are specified -- defaults & traits are automatically managed.


#!/usr/bin/env perl6



class ITDT {

    has $.itdt-path     = '/usr/local/ITDT/itdt';     # nice!

    has $.media-changer is required;                  # nice!

    has %!robot         = ( :ONE(1), :TWO(2) );       # nice!



    method robot        { %!robot; }

}



my ITDT $tape_library_inventory .= new(:itdt-path</opt/ITDT/itdt>,

                                       :media-changer</dev/smc0>);

say 'itdt-path:    = ' ~ $tape_library_inventory.itdt-path;

say 'media-changer = ' ~ $tape_library_inventory.media-changer;

print 'robot         = '; dd $tape_library_inventory.robot;



# output:

itdt-path:             = /opt/ITDT/itdt

media-changer = /dev/smc0

robot                     = Hash %!robot = {:ONE(1), :TWO(2)}

If you craft your own BUILD and/or TWEAK to perform more elaborate attribute 
initializations, then you must manage all of that yourself, losing the elegant 
‘has’ conveniences shown above.

I may have missed it.  new(), BUILD(), TWEAK(), !initialize – none seem to 
retain the magic of automatically managed defaults & traits.  Please enlighten 
me if it’s there and I’m not seeing it.

Thanks,

Mark


From: Timo Paulssen [mailto:t...@wakelift.de]
Sent: Sunday, October 1, 2017 16:56
To: perl6-us...@perl.org
Subject: Re: Perl 6 Object Construction - General Advice


I wrote another more in-depth (but potentially less useful to you) mail about 
this further down the thread, but I thought it'd be good to point this out near 
the top:

I think the self.bless(|%args)!initialize idiom is a work-around for submethod 
TWEAK not yet existing when this code was written. TWEAK works in a very 
similar manner, with these differences:

1) Your "self" isn't fully built when TWEAK runs, therefore you can't call 
regular methods on it
2) It will even be executed when a subclass of your class gets constructed, 
whereas there's no simple way to get access to !initialize from a subclass.
3) TWEAK gets passed the named parameters that bless was called with

method new is useful only if you want to take positional parameters for the 
.new — the default new you get from Mu only accepts named arguments and passes 
them on as-is to self.bless. They then get passed to every BUILD and TWEAK in 
the inheritance chain. The named parameters don't have to correspond to 
attribute names, as you can do any private attribute assignment in TWEAK that 
you like.
I hope that helps
  - Timo

Reply via email to