8

They seem to be used interchangeably in the documentation. Is there any difference, even in intent?

jjmerelo
  • 22,578
  • 8
  • 40
  • 86
  • 1
    The link at the very beginning said that `m/.../` is a regex that is immediately matched against $_. Isn't that the difference? – Sweeper May 01 '18 at 06:57
  • Yes, the article you're linking to points out the differences. `rx/.../`, like `/.../`, is a regex object with which you can match, whereas `m/.../` returns the match directly. – sshine May 01 '18 at 07:00
  • @SimonShine but they are used interchangeably in the rest of the text. besides, `say 'ðu' ~~ rx/.u/; say 'ðu' ~~ m/.u/; #OUTPUT: «「ðu」␤「ðu」␤» `m` is not matching against the $_ 'immediately' – jjmerelo May 01 '18 at 07:03
  • 1
    `m/.../` is analagous to an **explicitly and always immediately invoked** block of code like `{ say 42 }()` whereas `/.../` or `rx/.../` are analagous to a block of code like `{ say 42 }` which is **either** implicitly immediately invoked if it's in statement/sink context **or** just a block of code, not yet invoked, when it's used as a value. – raiph May 01 '18 at 09:01
  • @jjmerelo Interesting point. `m/.../`, used on RHS of `~~`, clearly does not technically match **immediately**. Instead it's immediately **after** the `~~` operator has set `$_` to its LHS argument. This is presumably related to the fact that `~~` is "a special form handled directly by the compiler". – raiph May 01 '18 at 09:24
  • 1
    (Just for a sense of completeness, I'm pretty sure `rx/.../` and `/.../` are interchangeable.) – raiph May 01 '18 at 09:30
  • 1
    See also [Why aren't // and m// exactly synonymous?](https://stackoverflow.com/a/45331353/215487) – Christopher Bottoms May 01 '18 at 18:50

1 Answers1

10

As the documentation you link to states,

m/abc/;         # a regex that is immediately matched against $_
rx/abc/;        # a Regex object
/abc/;          # a Regex object

[...] Example of difference between m/ / and / / operators:

my $match;
$_ = "abc";
$match = m/.+/; say $match; say $match.^name; # OUTPUT: «「abc」␤Match␤» 
$match =  /.+/; say $match; say $match.^name; # OUTPUT: «/.+/␤Regex␤»

So /.../ returns a Regex object that can be passed around as a value, and be used for matching later on and multiple times, and m/.../ returns a Match object having immediately performed the match. When you print a Match object, you get the result of the match, and when you print a Regex object, you get a textual representation of the regex. Using m/.../ in Perl 6 lets you access the implicit Match object, $/:

Match results are stored in the $/ variable and are also returned from the match. The result is of type Match if the match was successful; otherwise it is Nil.

The distinction is comparable to Python's re.compile vs. re.match/re.search, and a similar distinction exists in Perl 5 where you can store and re-use a regex with qr/.../ vs. m/.../ and /.../ for direct matching. As @raiph points out, not all occurrences of m/.../ and /.../ result in direct matching. Conversely, Perl 5 precompiles literal (static) regexes even when not explicitly asking it to. (Presumably, Perl 6 performs this optimization, too.)

Community
  • 1
  • 1
sshine
  • 15,635
  • 1
  • 41
  • 66
  • 3
    Oops, deleted my comment before noting that your edit relied on me leaving it in for details. But I cover the same point in my comment on the question. In P5 regexes are *strings* that may be compiled if they're entirely static. In P6 regexes are *code* that's always compiled but may have dynamic elements. – raiph May 01 '18 at 09:10