jeckyhl has asked for the wisdom of the Perl Monks concerning the following question:

hi monks,

I have a small perl6 program that basically rename all files in a directory, according to a given regex

I stuggled some time to get it work because I was using the match variable ($/) to do the filename replacement whereas I should have used the topic variable ($_)

This seems to me very conter-intuitive however. Could someone explain why I can't use $/ in this program ?

here's the code of the original version (doesn't works but if you replace $/[0] by $_[0] it magically works!)

#!/usr/bin/perl use v6; my Int $files_renames_count = 0; for dir(".") -> IO::Path $current_file { my Str $cur_filename = $current_file.basename; next if $cur_filename.IO ~~ :d; #skip directories (see http://doc. +perl6.org/type/IO) my Str $new_filename = $cur_filename.subst( /(.+)\.txt/, { $/[0] ~ " (2).txt" }, # doesn't works :( $/[0] is always +empty # works with $_[0] however (???) :i # case insensitive replacement ); if ($new_filename ne $cur_filename) { if ($new_filename.IO ~~ :e) { say "skipping file $cur_filename : $new_filename already e +xists"; } else { say "renaming $cur_filename in $new_filename"; rename $cur_filename, $new_filename; $files_renames_count++; } } } say "$files_renames_count files renammed";

i use perl6 version 2014.08-284-gfcdf308 built on MoarVM version 2014.08-108-g93d47dd

my OS is Windows7

Replies are listed 'Best First'.
Re: perl6 match variable
by Anonymous Monk on Sep 09, 2014 at 14:14 UTC

    The argument-less lambda block

    { ... }

    is shorthand for

    -> $_ { ... }

    and $/ gets passed as argument to that.

    You could use

    -> $match { ... }

    instead to access $/ as $match

    The match object $/ in not visible on its own because subst evaluates the regex in a different scope.

      luminous! thank you

      The match object $/ in not visible on its own because subst evaluates the regex in a different scope.

      Does it? Because when I write, e.g:

      say "foo".subst: /(fo)o/, {$/[0].flip}

      I get, as I expected, "of"

        And now let's try

        for dir(".") -> $file { say "foo".subst: /(fo)o/, {$/[0].flip}; last; }

        guess what happens ?...

        we get an empty string!

Re: perl6 match variable
by raiph (Deacon) on Sep 17, 2014 at 00:22 UTC
      Issue #118705 is marked as resolved but the problem is still there ??
      for 1 { say "foo".subst: /(foo)/, {$/[0] ~ "o"}; } #gives # Use of Nil in string context in block at <unknown file>:1 # o
      tested with perl6 version 2015.11-1-ge88196a built on MoarVM version 2015.11
        Bug 118705 talked about a similar looking set of bugs with the `s///` construct. This construct is a variant of, but not identical to, the `subst` function. It looks like a similar fix will have to be applied separately for `subst`. I've just filed a new `subst` specific bug report.

        Afaict the bug is omission of an automatically added `-> $/` signature. One workaround is to manually add the missing piece:

        for 1 { say "foo".subst: /(foo)/, -> $/ {$/[0] ~ "o"}; }

      Interesting, this would confirms that this is a bug and not a subtle spec interpretation issue