I’ve been meaning to write about this for a while, but truth be told I’m still not sure how it all works out. Still, I’m guessing some flawed knowledge is better than.. Well, No it’s not, but whatever.
But let’s introduce the topic first. Basically, I’m talking about this:
my $bad_example = '123456789'; substr($bad_example, 0, 6) = 'This sure is, '; substr($bad_example, length($bad_example) -3, 3) = "\nA bad example"; say $bad_example;
This works because certain functions work as lvalues – But that does bring the question, what’s an lvalue anyway?
The simplest answer, an lvalue is the left part of an assignment. Conversely, an rvalue is the right side of an assignment.
That’s a hard one to shallow, isn’t it?
Anyway, there are a few builtins that you can use a lvalues. I saw ‘a few’, because frankly, I only know of three — There’s probably whole lot more of them out there. They are pos, substr, and vec.
pos is simple enough: it returns the position from which the next //g regex will start looking. Every scalar has it’s own pos, which is set automatically after every match with the g modifier, or, more relevant to this post, you can set manually:
my $some_string = 'Why hello there'; pos($some_string) = 3; #Mandatory parens! say join ', ', $some_thing =~ /\w+/g;
Which will show “hello, there”, rather than all three words.
Assigning to substr, on the other hand, works something like a poor man’s four-argument substr – Rather than passing the replacement string as the final argument, you assign to the three-argument form:
my $other_string = "One day I'll get something entertaining to put in these."; substr($other_string, 27, 12) = 'AWESOME'; #Mandatory parens! say $other_string;
There are few reasons to actually use this, though. But for one, the three-argument form of substr has some magic in it, which you can see working in its perldoc entry. On the other hand, the four-argument form returns the substring replaced, and you don’t have to deal with any inner magic working behind the scenes, possibly against you.
Finally, vec. I don’t get vec, so this part might be lacking substance. More than the usual, anyway.
my $bitfield; vec($bitfield, 0, 32) = 0x5065726C; #Guess what those parens are! say unpack('b*', $bitfield);
I’m going to write an article about vec eventually, so any links, explanations, additions, or corrections, would all be welcome.
Well, that’s all for today. I would end these with some note of how cool what I just wrote about is, but either you already find it fascinating (here’s hoping!), or I’m not going to change your mind. Until next time, my non-existent readers!