Recently, I took a stab at learning Haskell, but that's not really where this meditation came from. I've always thought there should be a side-effect-less (I know, not a real word) way to do substitutions, so I don't have to explicitely copy over a variable.

my $first; ... my $second = $first; $second =~ s/some/substitution/;

Okay, okay, so this really isn't a big deal, but it's worse off when I'm doing a map...

my @output = map { my $temp = $_; $temp =~ s/some/subst/g; $temp } @input;

So today I was at work, not doing much, and I thought about the different ways I could do this, and I finally wrote a module. I'm wondering what you, my fellow monks, think about this.

So what I finally decided on is a source filter. I know, there are a lot of people out there that eschew source filters, but I think it may be the best way to do it. So I ended up with the ability to do this:

use Regex::FunctionalSubstitute; my $first; ... my $second = $first \~ s/some/subst/g;

and

my @output = map { $_ \~ s/some/subst/g; } @input;

Frankly, especially in the map case where map is meant to transform, this just feels right to me. Now, I'm not sure about the exact syntax... I decided on \~, but am certainly not set on it, for two reasons. 1: \ gives the look of "not binding" compared to = looks like "binding". 2: \ also is part of Haskell's anonymous sub syntax, which is sometimes what I think of when I think about Haskell.

I should mention what the source filter does and it's repercussions. The source filter changes: $identifier \~ s/some/subst/ into do { $temp_var = $identifier; $temp_var =~ s/some/subst/; $temp_var }. The problem with this is that $1, $2, etc., and everything involved in regex's will be out of scope, and therefore un-useable, so I would have to find a way to circumvent this, but this may cause similar problems to 'use English'. The source filter changes: $identifier \~ s/some/subst/ into ( $temp_var = $identifier, $temp_var =~ s/some/subst, $temp_var )[2] which has the effect of preserving $1, $2, etc. as well as returning the right value, both inside and outside map.

Well, enough explanation, here's the current code (definitely not finished).

package Regex::FunctionalSubstitute; use Filter::Simple; use strict; use warnings; my $identifier = qr/\$\S+/; my $operator = qr/\\~/; my $temp = '$Regex::FunctionalSubstitute::temporary_variable'; =head1 TODO Test Suite This documentation More accurate 'identifier' regex =head1 Conversion $this = $that \~ s/one/two/; converts to: $this = ( $temp = $that, $temp =~ s/one/two/, $temp )[2] =cut FILTER_ONLY( code => sub { my $ph = $Filter::Simple::placeholder; s{ ($identifier) # the source of the substitutio +n \s* # possible space between $operator # the operator '\~' \s* # more possible space between ($ph) # the regex itself } { ( $temp = $1, $temp =~ $2, $temp )[2] }gx; }, ); 1;

Update: Changed the transformation after fiddling with this for a while, so now $1, $2, etc. should be preserved.

    -Bryan


In reply to A Functional Substitute by mrborisguy

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.