Hello, Perl Monks!
I am putting together a Lightening Talk for Toronto.pm for tomorrow night on Perl's lvalue subroutines feature. For its "grand finale" I was hoping I could (more or less) recreate the lvalue version of substr, i.e.
my $graffito = 'Richard was here.';
substr($graffito, 8, 3) = 'is'; # now, it's "Richard is here."
As you can see in the following program and its output, I am "almost" there with my mysubstr lvalue subroutine. The part I've not figured out how to do is to somehow get the subroutine aware of what the rvalue in the operation is.
Please read my comments in the program to see where my
line of thinking is going.
rdice@tanru:~$ cat lvalue2.pl && ./lvalue2.pl
#!/usr/bin/perl -w
######################################################################
#
# lvalue2.pl
# Another quick, dirty and simple program meant to
# illustrate the creation and use of lvalue subroutines.
# This is part of my "What Fresh L is this?" Lightening
# Talk for the Toronto Perl Mongers, Thu 26 Sept 2002.
#
# Author: Richard Dice (rdice@pobox.com)
# Date: Tue 24 Sept 2002
#
######################################################################
use strict; # Always use strict. ALWAYS USE STRICT.
my $graffito;
$graffito = 'Richard was here';
print ((substr($graffito, 8, 3) = 'is'), "\n"); # to see return valu
+e
print "$graffito\n"; # to see end result
print "\n"; # whitespace between
+ outputs
$graffito = 'Richard was here';
print ((mysubstr($graffito, 8, 3) = 'is'), "\n"); # to see return valu
+e
print "$graffito\n"; # to see end result
# Were 'mysubstr' to work correctly, then the two outputs should be
# identical
exit 0;
sub mysubstr : lvalue {
my @chars = split //, $_[0];
my $pos = $_[1];
my $width = $_[2];
# Wouldn't it be nice if the rvalue was added onto the end of @_?
# As it stands, I have no idea how to get at the rvalue. I'll
# just pretend that this is how it should be handled for the sake
# of this example.
my $rvalue = $_[3];
# For all you pedants out there, I know that my algorithm for
# putting the string back together doesn't exactly equal what
# the real 'substr' function would at its edge cases.
# That's not the point of this example.
$_[0] = (join '', @chars[0..$pos-1])
. $rvalue . (join '',@chars[$pos + $width .. $#chars]);
$rvalue; # This seems like the easiest way to return what the
# real 'substr' returns without mucking anything up.
}
is
Richard is here
Use of uninitialized value in concatenation (.) or string at ./lvalue2
+.pl line
54.
is
Richard here
rdice@tanru:~$
Any ideas, folks? Btw, I'm running 5.8.0, but this should
work (if indeed it did work) back to 5.5.3 at least.
Cheers,
Richard