The /o in Ruby regex stands for "oh the humanity "
19 comments
·August 2, 2025riffraff
Unsurprisingly, `END {}` is also inherited from perl, tho I think it originally comes from awk.
mdaniel
Similarly unsurprisingly, with its BEGIN friend https://docs.ruby-lang.org/en/3.3/syntax/miscellaneous_rdoc....
In the spirit of "what's old is new again," PowerShell also has the same idea, and is done per Function with "begin", "process", "end", and "clean" stanzas that allow setup, teardown, for-each-item, and "finally" behavior: https://learn.microsoft.com/en-us/powershell/module/microsof...
mananaysiempre
Oh, that’s an interesting take. I’ve long been looking for newer developments on Awk’s clause structure, and this seems like an interesting take (though I’m unclear on whether I can have multiple begin/end clauses, which are the best thing about Awk’s version). It also finally connects this idea to something else in my mind—specifically advice[1] and CLOS’s :before/:after/:around methods[2]. (I guess Go’s defer also counts?)
[1] https://en.wikipedia.org/wiki/Advice_(programming)
[2] https://gigamonkeys.com/book/object-reorientation-generic-fu...
mdaniel
It seems not:
Given:
function Fred {
begin {
echo "hello from begin1"
}
begin {
echo "hello from begin2"
}
process {
echo "does the magic"
}
}
$bob = @("alpha" "beta")
$bob | Fred
Then $ pwsh fred.ps1
ParserError: /Users/mdaniel/fred.ps1:5
Line |
5 | begin {
| ~~~~~~~
| Script command clause 'begin' has already been defined.
cbsmith
As an old Perl programmer, I knew immediately what the /o would do. ;-)
Amorymeltzer
I've always loved the recent[1] summary from `perlre`:
>o - pretend to optimize your code, but actually introduce bugs
1: I still think of it as a relatively new change, but it's from 2013: <https://github.com/Perl/perl5/commit/7cf040c1f649790a4040aec...>
kstrauser
It's older than that. The article links to this conversation about it in 2003: https://www.perlmonks.org/?node_id=256053
rco8786
Love these sorts of deep dives, thanks!
lupire
This is the same problem people have with closures, where it's unclear to the user whether the argument is captured by name or by value.
layer8
This isn't the same problem, because this is about whether the regex is instantiated each time the code around the regex is executed, or only the first time and cached for subsequent executions. The same could in theory happen with closures, but I haven't ever seen programming-language semantics where, for example, a function containing the definition of a closure that depends on an argument of that outer function, would use the argument value of the first invocation of the function for all subsequent invocations of the function.
For example, when you have
fn f x = (y -> x + y)
then a sequence of invocations of f f 1 3
f 2 6
will yield 4 and 8 respectively, but never will the second invocation yield 7 due to reusing the value of x from the first invocation. However, that is precisely what happens in the article's regex example, because the equivalent is for the closure value (y -> x + y) to be cached between invocations, so that the x retains the value of the first invocation of f — regardless of whether x is a reference by name or by value.phoronixrly
It's kind of a cool feature. I like it.
thayne
Is it? I can't think of a non-contrived case where this would actually be useful.
And in any case where it would be useful, it seems like a better way to optimize would just be to refactor the regex out into a constant.
zer00eyz
Im sorry but the classics never go out of style:
"Some people, when confronted with a problem, think 'I know, I'll use regular expressions.' Now they have two problems."
stavros
Yeah but it's kind of tired when it's being used every time someone makes a mistake with regex. I've used them extensively in my career and never once regretted it.
apgwoz
The problem with regexps is that “Sometimes a smart person, who has done the work, and knows how to leverage regular expressions correctly, decides they are appropriate for solving a problem where there is shared maintenance. Now, you have people who haven’t put in the work, and have been told repeatedly through ‘witty quips’ to not bother.”
jodrellblank
The second problem being how to deal with all the extra time they just freed up?
Joker_vD
> I didn’t recognize /o. It didn’t seem critically important to lookup yet.
> With nothing else to investigate, I finally looked up the docs for what the /o regex modifier does.
I'll probably never understand this mode of thinkning. But then again, Ruby programmers are, after all, people who chose to write Ruby.
> /o is referred to as “Interpolation mode”, which sounded pretty harmless.
Really? Those words sound quite alarming to me, due to personal reminiscences of eval.
Also, this whole "/o" feaure seems insane. If I have an interpolation in my regex, obviously I have to re-interpolate it every time a new value is submitted, or I'd hit this very bug. And if the value is expected to the same every time, then I can just compile it once and save the result myself, right? In which case, I probably could even do without interpolation in the first place.
apgwoz
“Compilation”, I think, is exactly right. This feature is less about interpolation than it is about compilation of a single regexp to be used many times. It’s just shrouded in confusing documentation that should say: “/o tells ruby to rewrite this code such that it refers to a new statically allocated regexp object.” And when you write it that way, you see how insane it is for a function call to be hoisted automatically like this, without an explicit, obvious, syntactic annotation.
This is one of the features that Ruby cribbed directly from Perl. The Ruby documentation seems really bad, in particular “interpolation mode” is grievously misleading.
Perl’s documentation is far more clear about the consequences:
(https://perldoc.perl.org/perlop#Regexp-Quote-Like-Operators)
In the days before Perl automatically memoized the compilation of regexes with interpolation, even back in the 1990s, it said, Perl 4’s documentation is briefer. It says,(https://github.com/Perl/perl5/blob/perl-4.0.00/perl.man#L272...)