How prevalent is `try` in rails/activesupport? My benchmarks show that the lonely operator is ~2x faster than `try`. I'd expect someone to create a gem that monkey patches `try` for those running 2.3.0.
`try` is different from `try!`. the new lonely operator is like `try!`, which asks only if the object is nil and then calls the method on it if it's not (and will blow up if the object doesn't have the method publically defined). `try`, in contrast, asks if the object is nil or responds to the method and returns nil if it doesn't.
There isn't really anyway to monkeypatch `try` to use the operator. `try` API is inherently based on metaprogramming (passing a symbol to call), and have different semantics than the operator (by default it won't throw if a non-existent method is called in a non-nil object, while the operator will thrown a NoMethodError)
Using `try` is definitely a code smell, but unfortunately it's often a necessary one in production environments that have seen some wear and tear in the integrity of their database structures.
Keep in mind string literal freezing is still off by default.
I like that they did it this way, give a chance to see if it actually brings performance improvements in real world scenarios before imposing it on all code.
It's really great to see that with every big release, Ruby is making the language even more pleasant to use in addition to the regular performance improvements.
Nice to see "Did You Mean" suggestions flourishing across various tools now, e.g. Git too. Error messages can be a whole lot more than indecipherable jargon, even for command-line warriors.
I'm also looking forward to never writing "if foo && foo.bar" again!
As Chris Seaton points out as well, we're not really open source yet. Working on getting there, but it's going to take time. The important thing now is that we can start talking with the community and making it more likely that when we do get open source, it can happen in a way consumable by the Ruby community.
I can tell you that I tried your fork on some toy projects and.. nothing really to report, other than, I'm really scared something this good won't go anywhere.
I don't think that will happen for a while, if it does happen. They haven't even released their patch under a compatible licence yet, or their library as open source, for example.
Thanks for reposting this. Wonder why it's not making bigger waves. What are the performance numbers of this thing like? I feel this IBM OMR is a reply to MS opening .Net CLR
Looks like some nice additions. I try to limit the use of .try in rails, however when working with legacy codebases it is much nicer then:
if @user && @user.address && @user.address.city
city = @user.address.city
end
Even though I write less Ruby then I once did, I still credit it as the language which shaped my career the most. I have worked so many great jobs because of Ruby.
I could see it making deployment faster or nicer. Imagine being able to compile all the byte code for a Rails app locally and just shoving that up instead of waiting on bundling and all that.
Also I think this would make possible hot code upgrades which are cool but probably more work than their worth. Unless you can build smart hooks into background job and web server libraries that only change the byte code in between jobs and requests. Oh the possibilities!
After reading the patch that introduced the byte code compilation it seems what I was hoping to use it for are clearly not goals of the project: https://bugs.ruby-lang.org/issues/11788
I was curious just like you and gave this a try too. Seems that while the project is intended for this you can easily build this. Thank you for writing that up!
- migrate obfuscate binary to other node to hide source code
---
But.. what I don't get is: why wouldn't this works as a cheap way to obfuscate some ruby code?
After all, isn't it true that when a script is compiled to byte-code then it is interpreted by the runtime as-is (and without being re-translated to the original script in memory or on disk) ?
If so - I understand that rebuilding the original ruby script would not be a big deal for a developer - but wouldn't this still pose a small barrier to the casual prying user?
For my money, Ruby comes closest to realizing the "promise" of dynamic languages. That is, it's fast to build with when prototyping, flexible when refactoring, reasonably fast enough and not so memory hungry that it can't handle "web scale".
Obviously there are languages that are better in each of these areas, but few that combine so many as well as Ruby. In other words, if you know that you'll be working in a problem domain (e.g. high concurrency) where specific advantages of some other language (e.g. Go/Erlang) are likely to be needed, use that language. If you're just building something, then Ruby's a fine place to start.
The Rails ecosystem is mature now, which means you can find an off-the-shelf gem to do just about anything you want. So building things in Rails is very very fast. It's hard to beat for MVP-style development.
For me: because nothing else approaches it in terms of linguistic flexibility. I learned Ruby about two years ago, after learning...a dozen-ish languages? Something like that. I don't write web applications in it, because Rails grinds my gears for a whole host of reasons, but for my money it is the can-opener language. If I have a problem, I feel like I can generally explore it faster in Ruby (holla, Pry) and build a solution iteratively without really burning a lot of mental effort on it.
The second part, aside from Ruby's general applicability and ease of exploration, is that I think Ruby scales, in terms of application design, from that garbage-y first-cut code to really elegant, really clean code that's fun to work in and easy to maintain. That first solution, borne mostly out of dumping my REPL history, may not be great, but that's okay: with the help of the excellent ecosystem around the language I can reify my expectations in tests and swap out the original exploratory system for good, easy-to-work-with code that's clear in its behaviors. Of course you can do that with other languages, too--but I've never found one that makes it as easy to stretch in both directions, from noodling around to code I'd trust with my business (and I'm doing exactly that), other than Ruby.
But as for the languages you namedropped:
- Perl 6 is great, but it's a decade late and it isn't sufficiently compatible with Perl 5, so it's starting miles and miles behind where Ruby is right now. It's not dead out of the gate, but it keeps lurching toward the green and making everybody nervous. Practically nobody knows Perl 6 now, I don't know why somebody would pick it over Ruby if they're lining both languages up side by side.
- Clojure is super interesting and Rich Hickey is a supergenius and we're all lucky he didn't go into supervillaining because I think he'd be really good at it. And Leiningen is an amazing build system. But Clojure suffers from what I view are the usual problems a Lisp has around readability and the hands-on-keyboard experience (and I like Lisp, I've got DrRacket installed on my laptop for a reason, but I've been writing Lisps for a decade or more now and grinding out Clojure code is slow). Love the people, love the community...would rather write Ruby.
- Rust doesn't do nearly the same thing as Ruby. They're useful for different things. I feel like Rust inherited the good parts of the Ruby ethos from the participation of folks like Steve Klabnik. Big fan of the language and the community, but it's not incompatible with Ruby where it matters anyway so who cares?
- F# is a great language and, like Rust, also has little overlap with what I use Ruby for. If I cared about Ruby for the web, maybe there would be more overlap, but F#-for-web is swimming upstream anyway. (Doable, but harder than C#.)
- Go, while it as a language deserves some small credit for introducing co-routines to people who come from Python (he said, only somewhat snarking while he makes Lua gang signs), is close to an unmitigated disaster of an ecosystem that tries to be prescriptive when it should be hands-off and hands-off when it should be prescriptive. It is also a tremendously limited language in terms of syntactic flexibility and ability to do stuff like "second-order" metaprogramming; this is a design decision that can be debated, or could be debated if I hadn't been convinced long ago by better languages that crippling a programmer to make writing an execution environment easier to always be the wrong thing. Do not want.
I have, actually. I really like the idea of it and the project is super impressive (bootstrapping as quickly as they have is legit!), but in practice it doesn't feel right to me. A lot of it is library fit, but a lot of it is inherent to the way that Crystal works. I, personally, find relatively heavy metaprogramming to be super valuable and to make me significantly more productive with my tools. I live on `instance_eval` and `send`, and Crystal's flavor of compile-time macros doesn't do it for me.
I love that it exists, and as it matures I will totally consider it for Big Time Web Application Development (for me that's Kotlin right now). But I don't think it'll ever be quite as "stretchy" as Ruby is, and Ruby's a good all-purpose language, for me, because of that stretch.
I've used both Elixir and Erlang, but as eropple said about other languages, I feel they solve different problems from Ruby. It's also no way near as mature/popular, so a lot of things you may need to write yourself instead of using an off the shelf gem.
It's got an elegant syntax, great for meta-programming (tends to be useful in large and/or complex applications), strong community (there are gems for almost everything, i.e. no need to reinvent the wheel over and over again).
It's used by some interesting applications, such as Github, Shopify, Heroku, Square, Zendesk and AirBnB.
if everything came down to just what you type in the editor (e.g. functionally equivalent programs in any language performed the same everywhere), i would always prefer ruby.
it's just a nicer language to use than most, or maybe all others.
'try' is relatively slow compared to other control logic, as allowing an exception to be thrown involves constructing an exception stack trace. This is slow in all VMs I know. Theoretically you could detect that the trace isn't used and remove it through escape analysis, but this is not easy, or you could do some crazy thing with lazily creating the stack trace, but that's a research project.
yes. care to elaborate? first thing that came to mind was "APC-style" (https://secure.php.net/manual/en/intro.apc.php) caches. but im not super up on deployment, i thought YARV was already supposed to achieve this.
APC exists because PHP reloaded source files each time a script was executed through your webserver. No such parallel exists in Ruby; once source files are loaded in a process, they stay loaded for that process.
In theory it might allow for faster loading of Ruby code (more analogous to Python's .pyc files), but IIRC early experiments (in the early 2.0 days) showed it to be counterproductive in many cases.
`&.` removes the really annoying (and slow) `try`.
And I think the string literals freezing is going to solve a lot of problems with memory allocations.
Check out this PR for Rails that covered a lot of similar performance problems created by too many string allocations.
https://github.com/rails/rails/pull/21057/files
I wish Rails 5 could go all in on Ruby 2.3.0 and frozen string literals.