The other major thing I like about JRuby is that it's much easier to hack on than MRI - the Java code is extremely clean and easy to understand, and it's easy to use tools like IntelliJ's debugger to diagnose issues quickly and easily. I've contributed dozens of commits to JRuby specifically because the barrier to entry is just a lot lower than it is in MRI.
The community is really, really good, and the project is extremely hackable - it's an embodiment of the best in open source, IMO, and I'm really excited for this release in the hopes that it gets more people using it.
I will echo what others have said, though...closures capture and share a lot of other state. $~ and the related vars like $1 are supposed to be "special" but there's other state you're going to stomp on all Ruby impls. It's better to avoid using closure state if you know it's going to be called across threads, because most of that state will be shared on all Rubies.
I'll admit to encountering weird "er, why is that randomly nil" errors quite regularly with JRuby when load testing webservers, which, er, I've never reported. It's never been obvious where the fault was, really. And it always seemed unlikely to be your fault, tsk ;)
> It's better to avoid using closure state if you know it's going to be called across threads
Yeah. In this case it was a hash of name -> lambda pairs which boiled down to variations on:
->(obj) do
case obj.bla
when /foo(.*)/ then "FOO_#{$1.upcase}"
when /bla(.*)/ then $1
end
end
Called in lots of tight loops from a pool of worker threads. I refactored it into something neater, but it still should have worked fine :)Do I understand things right, or am I wrong here?
I guess the question is where the regexp special vars are scoped to though, I see how that's not entirely clear.
def f
p $~ # => nil
"123" =~ /\w+/
p $~ # => #<MatchData "123">
end
p $~ # => nil
"abc" =~ /\w+/
p $~ # => #<MatchData "abc">
f
p $~ # => #<MatchData "abc">Considering threading is the main selling point, one of the commonest patterns of regexp use being completely and dangerously broken with them would have seemed like something of a showstopper.
I can see wanting it fixed, but it's a pretty odd hill to die on.
Is it really? Even fairly early in the Ruby 1.8.x era, most recommendations I saw were that the magic regexp globals (and many other magic globals) were a perlism that should generally be avoided.
If avoiding `$1` has been often recommended for a while... I think it's a recommendation more often ignored than followed.
time, benchmark, irb, pry, rubygems, resolv, erb, rake, open-uri, debug, rack, cgi/util, optparse, getoptlong, bundler, activesupport, actionpack, activemodel, erubis, slim, haml, sass, sequel, roda, nokogiri, rugged, faraday, mime-types, thor, test-unit, tzinfo, mail, ffi
However, not all bugs are made equal and this one seems relatively likely to actually cause problems for users. Wouldn't someone running some service and handling say 10 requests/second, while using the regex global variables, run into this bug on a daily basis?
So I guess I'm just interested in how such a decision is made: what bugs get shipped and which block a release?
If this bug would reasonably cause problems in such a situation and if the policy of JRuby is to ship anyway, that seems to be a relevant piece of information to consider for someone using JRuby in production and considering whether to upgrade.
Perhaps one should always check the list of open bugs for the version of a compiler/interpreter one intends to start using, but I've never done so, haven't been bitten by a bug yet (AFAIK) and yet this one seems one that could be a problem. The main problem is of course that this may just be 'the curse of knowledge' in play.
So I guess I was being a bit dismissive towards OP, then I was sympathetic and now I'm mostly thinking about how I should handle this as someone using JRuby in production. Perhaps I should just ignore it. Perhaps I should investigate the set of concurrency tests and contribute a few. Perhaps I should be conservative and only use 'proven' JRuby versions. Perhaps I should learn to stop worrying and love the bomb :)
Stumbling over a serious race condition in the first 5 minutes of trying it with real code makes me a bit wary. All the performance in the world isn't much good if it's randomly wrong :/