abstract classes
derived classes / polymorphism
attribute type constraints
delegation
encapsulation
composition (roles)
immutable state
and so on
And many people did roll their own, which resulted in Moose (Moo, et al) on CPAN, which have evolved to be some of the best in class (ha) object system frameworks and features across any language.Now the plan is to get that into the core, and this is the first step.
No serious Perl developer has been using bless for OO for a least a decade, unless they were constrained by micro optimisations and/or not being allowed to use non-core dependencies.
And at least p3rl.org/Moo works with p3rl.org/App::FatPacker because I designed them to play nice with each other.
I once fatpacked an http://p3rl.org/Eval::WithLexicals tinyrepl on the fly mid-conversation for Bruce Momjian of postgresql fame.
He wanted to try a repl with persistent lexicals but his NetBSD install was getting sufficiently long in the tooth he didn't want to risk running CPAN on it - and fatpacking a script I had handy was a lot quicker and more effective in terms of getting him to try something out than trying to convince him to let me walk him through a local::lib setup.
Now that APPerl XS support has improved, I want to play again with it again.
Earlier this year, I did fatpack few things in a "dirty" way: by adding them to APPerl.
Still, this gives you a perl.com working anywhere, with all the modules you need, executing by default the payload of your choice.
I had a lot of fun writing a very barebonne webserver (https://github.com/csdvrx/PerlPleBean), along with a few side utils to do mDNS to expose the webserserver on .local (https://github.com/csdvrx/PerlPleBean/blob/main/experiments/...), run perl scripts on uploaded files etc
Someone with your experience could certainly do many more interesting things with APPerl :)
Ok, I do actually have a hilariously awful trick that manages to wrap DynaLoader to read from a Base64 encoded .so that's inlined into the fatpack but that was more a "wondering if I could" thing than something I've ever felt the urge to actually use in anger so I've (so far) resisted the siren song of CPANing it anyway because people have an unfortunate tendency to forget that I, too, release things that are terrible ideas sometimes.
(though being able to use XS modules with a single file you squirt over an ssh connection ala Object::Remote without needing to write anything to disk is kinda fun, especially when you do it with DBD::SQLite ;)
APPerl sounds like it could be awesome, App::staticperl is the closest to it I've looked at so far, though since APPerl definitely wants to write to a non-noexec filesystem I wouldn't be surprised if I there are cases where if I had that and a toolchain available I'd end up using it to run Perl::Build to bootstrap a more normal perl and then go from there.
Either way, thank you very much for pointing out APPerl's existence to me. Even if I don't end up using it myself, having it in my mental index of available crazy things will almost certainly eventually result in my suggesting it to somebody else who'll find it the least insane way of getting the results they need :D
That must be quite a timesink lol :)
> Ok, I do actually have a hilariously awful trick that manages to wrap DynaLoader to read from a Base64 encoded .so that's inlined into the fatpack but that was more a "wondering if I could" thing than something I've ever felt the urge to actually use in anger so I've (so far) resisted the siren song of CPANing it anyway because people have an unfortunate tendency to forget that I, too, release things that are terrible ideas sometimes.
Actually, I think that could be a great idea for cosmopolitan binaries!
Right now, you have to recompile perl to add the XS you want, and some don't work yet: it all depends on the build tool for the XS module being supported
So could you please tell me more about your trick? (or just link to it, I kinda get the idea but an actual example might help)
> APPerl sounds like it could be awesome
It already is: the perl.com binary is a polyglot zip file, where you can fatpack perl scripts by appending them to the zip file
If you've got 5 min, run perlplebean.com: just be careful, as by default I expose your filesystem for http requests. Just comment out that part if you don't like it (it's meant to make people check and tweak the source)
> APPerl definitely wants to write to a non-noexec filesystem
Yes, perl.com has to be executable :)
But on Linux, you may be able to use ld-loader to run it (like how a .sh script on a nonexec fs can be run as `sh -c file.sh`)
> Either way, thank you very much for pointing out APPerl's existence to me. Even if I don't end up using it myself, having it in my mental index of available crazy things will almost certainly eventually result in my suggesting it to somebody else who'll find it the least insane way of getting the results they need :D
Sure, feel free to get in touch at my nick at outlook.com!
It's a bit strange for me to dig into perl now, while it was "current" more like 20 years ago, but I just love it!
All I need is magic structs with methods and that provides it. Throw in a constant array of properties and an AUTOLOAD, and you have accessors if you need it.
Generally you'd use one of the M* systems - p3rl.org/Moo or p3rl.org/Mojo::Base or p3rl.org/Moose - the last one having a full metaprotocol, the other two being rather lighter weight but still with enough features to keep you relatively sane.
The new system is actually not that dissimilar to those in terms of the conceptual model even where the names and syntax are slightly different, so anybody who's been writing production OO code in the past ten years shouldn't have that much trouble switching across.
* `bless` and `class` aren't topologically equivalent: you can't twist and warp one into the other
* We've seen small, incremental steps get beaten to death by bike-shedding every step
* Sometimes it's hard to see the big picture when you're looking at the individual details
It's that first point that's really the killer here. Perl used `bless` and `@ISA` ("we have methods" and "here's where to find them") and that was all.
You want state? Figure it out.
You want encapsulation? Figure it out.
You want to work around MRO bugs? Figure it out.
You want to know if something in the symbol table is a subroutine or a method? Figure it out.
You want composition? Figure it out.
Much of what we wanted just couldn't be easily done building on a broken foundation, but there's so much excellent work out there which already solves these problems for class-based OO, we decided to take advantage of what others have already learned.
{ package Point;
use Moose;
has 'x' => (is => 'ro', isa => 'Int', required => 1);
has 'y' => (is => 'ro', isa => 'Int', required => 1);
sub as_string {
my $self = shift;
return sprintf '(%d,%d)', $self->x, $self->y;
}
}
my $origin = Point->new(0, 0);
say $origin->as_string;It wouldn't hurt other languages to have a higher order object templating system.
Other things it did right is the taint flag to keep user supplied data from hitting sensitive functions by way of the type system. (In Rust you can declare your own type to achieve this, and it's actually enforced.)
The unicode system was actually decent in ways nothing else is, at least until the Go and Rust generation. Python 3 wasn't nearly as complete despite being more than a decade later.
If people ask what Perl did wrong, the dereferencing syntax is at the top of my list. Not having multidimensional arrays as a first class type probably did more to scare people away than anything else.
my $aref = [1,2,[3,4,5,[6,7] ] ];
You can do print $aref->[2][3][1];
which yields: 7
Or my @array = (1,2,[3,4,5,[6,7] ] );
print $array[2][3][1];
7 class Point {
field $x :param :reader;
field $y :param :reader;
method as_string() {
return "($x,$y)";
}
}
my $origin = Point->new( x => 0, y => 0 );
say $origin->as_string;
I know which of the two I'd rather write :)The main limitation is that we don't have the `isa => 'Int'` check. That's largely because adding types is something for the entire language, not just this new syntax, so it had to be delayed.