Front page | perl.perl5.porters |
Postings from June 2019
Re: Making join() respect string-concat operator
Thread Previous
|
Thread Next
From:
Paul "LeoNerd" Evans
Date:
June 14, 2019 15:08
Subject:
Re: Making join() respect string-concat operator
Message ID:
20190614160809.7b2faf37@shy.leonerd.org.uk
There are some exciting discussions happening on this thread, but not
really going in the direction I intended to go.
Let me maybe start again.
TL;DR: I want to be able to write stringy algorithms that work nicely
on overloaded objects, the way that numerical algorithms already do.
Observe, in Perl, that we have a rich set of numerical operators for
doing all sorts of complicated maths work. Observe also that they all
form a nice well-behaved set with respect to operator overloading,
allowing such modules as Math::BigRat to exist. This allows someone to
write a numerical algorithm, say, without any knowledge or upfront
design to take bigrat in mind, and yet because the operators all play
nicely, a user can trade runtime for precision and use Math::BigRat to
get answers as precise as they want.
Compare this to the relatively operator-poor world of strings. I have
written a module, String::Tagged, which acts and feels like a string
but stores extra data in extents across it, typically used for
formatting or similar. Because perl's string operators aren't anywhere
near as nicely overloadable, I can't put these objects into some random
string-processing module, say, Text::Wrap, and have it Just Work in
anywhere near the same neatness as Math::BigRat works for numbers.
It does feel a shame that Perl, a language that it traditionally good
at text manipulation, can only manipulate plain strings in such a nice
way, and doesn't let you add extra semantics to string-like object types
and actually have them behave with the core operators.
I did start off on an experiment to see how easily I could fix this;
already I've created overload::substr which adds a new `substr`
overloading slot:
https://metacpan.org/pod/overload::substr
This actually works, provided the module is loaded early (because it
does Evil Evil Things). With this module loaded, any string-like object
class such as String::Tagged now behaves nicely with respect to the
substr() core function. Other modules, such as Text::Wrap, don't now
have to care at all - they can operate on String::Tagged (or any other
stringy object class) transparently.
Via a bit of learning how the regexp engine works I could use the same
trick to make split() use the same substr operator to extract the
"pieces", as well as maybe make regexp match and substitution work.
While I'm there I could have join() behave with string concat.
I am somewhat hesitant to do that in the manner used in this module,
because of the Evil Evil Things alluded to above. What I do is replace
the core PL_ppaddr[OP_SUBSTR] with a pointer to my own overloaded logic:
https://metacpan.org/source/PEVANS/overload-substr-0.03/lib/overload/substr.xs#L201
This doesn't work for any code that has already been compiled, so the
entire hack is very sensitive to the exact order that modules are
`use`d. In addition, I don't know of a way that a module which isn't
core perl can nicely provide the $1, $2, ... variables in a lazy way. I
could perhaps pick a static number, say 10, and fix those, but then it
would break for $11. Only core perl via its various magic tables, can
implement that at all.
It would be nice if support for these overloaded operators was moved
into core perl, so that module load order didn't matter, and then it
would become possible to write nice string-like object classes which
actually behave properly against text processing algorithms.
Such as Perl is famous for.
Thanks,
--
Paul "LeoNerd" Evans
leonerd@leonerd.org.uk | https://metacpan.org/author/PEVANS
http://www.leonerd.org.uk/ | https://www.tindie.com/stores/leonerd/
Thread Previous
|
Thread Next