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:[email protected]]
Sent: Sunday, October 1, 2017 16:56
To: [email protected]
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