
Ruby 2.3.0 Released - cremno
https://www.ruby-lang.org/en/news/2015/12/25/ruby-2-3-0-released/
======
matthewrudy
This is actually a really great release.

`&.` 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](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.

~~~
anonova
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.

~~~
matthewrudy
`try` is bad for a number of reasons.

Because itll never throw an error, you see it hiding issues.

And I keep seeing colleagues writing `hash.try(:[], :some_key)`

`try!` is better.

But I'll stick to `&.` from now on.

~~~
kelseydh
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.

------
dmerrick
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.

Ruby just keeps getting better and better.

~~~
pwelch
Agreed. Been using Ruby for a few years now and it never stops being
enjoyable. Hoping it keeps going for many more years!

------
shinuza
Fun fact: Ruby 1.0 was released 19 years ago on this day.

------
mmahemoff
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!

Congrats and happy holidays Ruby team :).

~~~
cdcarter
Well, git's "did you mean" is probably the most frustrating command line
experience imaginable, but it's quite nice in a language!

~~~
dmerrick
It's the worst when it says something to the effect of "you made a typo, so we
already ran this unrelated command for you!"

Tip: run the following to add a 1-second pause between the message and the
"fixed" command being executed:

    
    
      git config --global help.autocorrect 10

------
smegel
I seriously saw this and thought it might be the reason for the ruby-colored
banner.

 _facepalm_

~~~
hartator
We can say it's for both Christmas and Ruby relesae. :)

~~~
smegel
The fact that Christmas is almost over where I am - and I saw the normal
banner all day - might explain it :)

------
ksec
Anyone knows if Ruby has accepted IBM's contribution of JIT for Cruby??

[https://news.ycombinator.com/item?id=10715610](https://news.ycombinator.com/item?id=10715610)

And below is the Presentation from Ko1 on compiling Ruby

[http://rubykaigi.org/2015/presentations/ko1](http://rubykaigi.org/2015/presentations/ko1)

~~~
magaudet
(IBMer working on said JIT here)

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.

~~~
claudiug
do you have any status of the project? Or any dates when we can expect?

~~~
magaudet
Unfortunately no dates. We're still working on this, but we really want to do
it right, so we're taking the time we need. Sorry!

------
r-s
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.

~~~
gkop
Yup. In addition to the general purpose safe navigation operator we also have
Hash#dig now which helps with those pesky nested params:

params.dig(:user, :address, :city)

------
omarforgotpwd
Ah, YARV finally adds bytecode compilation and loading as an "experimental"
feature. It'll be interesting to see what people do with it.

~~~
rubiquity
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!

~~~
rubiquity
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](https://bugs.ruby-
lang.org/issues/11788)

~~~
pmontra
I'm not sure the prospects are so bleak. I made some tests and I could run the
compiled code on another machine with a different directory structure. See
[https://ilconnettivo.wordpress.com/2015/12/25/ruby-2-3-0-ins...](https://ilconnettivo.wordpress.com/2015/12/25/ruby-2-3-0-instructionsequence/)

~~~
rubiquity
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!

------
singularity2001
Here are two bash functions so that you can compile and execute the bytecode
in the terminal:

i.e.

rubyc test.rb

ruby-do test.rbc

in .bashrc:

function rubyc() {

ruby -e "File.open('$1c',
'wb').write(RubyVM::InstructionSequence.compile_file('$1').to_binary)"

}

function ruby-do() {

ruby -e "RubyVM::InstructionSequence.load_from_binary(File.open('$1',
'rb').read).eval"

}

------
systems
with the existence of Perl6, Clojure, F#, Rust, Go, and few others ...

For someone who doesn’t know Ruby, why learn it today?

~~~
eropple
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.

~~~
erokar
What about Elixir?

~~~
eropple
Never used it. Looks nice enough? But never looked like something I'd open in
a REPL to hash out a problem. Could be wrong.

------
edlebert
I couldn't find any actual examples on how to use the new frozen string
literals. Lots of discussion in the link provided, but that's it.

~~~
itafroma
The NEWS file defines what the pragma actually is,[1], but you'd use it like
so:

    
    
        # frozen_string_literal: true
        str = 'foo'
        str << 'bar'
    

This will now produce an error:

    
    
        # main.rb:3:in `<main>': can't modify frozen String (RuntimeError)
    

It's equivalent to Ruby 2.1's String#freeze:[2]

    
    
        str = 'foo'.freeze
        str << 'bar'
    
        # main.rb:2:in `<main>': can't modify frozen String (RuntimeError)
    

Except that it will affect all strings created after the pragma mark.

You can also trigger this behavior globally with the --enable=frozen-string-
literal option.

[1]:
[https://github.com/ruby/ruby/blob/v2_3_0/NEWS#L17-L26](https://github.com/ruby/ruby/blob/v2_3_0/NEWS#L17-L26)

[2]: [http://ruby-doc.org/core-2.2.3/Object.html#method-i-freeze](http://ruby-
doc.org/core-2.2.3/Object.html#method-i-freeze)

------
waylandsmithers
Interested to see how people start using safe navigation! I personally tend to
avoid `try` in Rails in favor of other `nil` handling patterns.

~~~
hopsoft
Why? Genuinely curious.

~~~
chrisseaton
'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.

~~~
jrochkind1
I think you are confused, `try` is not raise/rescue. The ActiveSupport `try`
implementation does not involve allowing an exception to be raised.

[https://github.com/rails/rails/blob/v4.2.5/activesupport/lib...](https://github.com/rails/rails/blob/v4.2.5/activesupport/lib/active_support/core_ext/object/try.rb#L69-L80)

It should be as performant as other ways of checking for nil/empty.

~~~
chrisseaton
Ah yes you're right - I was confusing this with raise/rescue.

------
DevKoala
I love '&.'

I really missed this feature from C# 6.0

------
diminish
Does lonely operator support safe navigation in case of method calls with
params too?

    
    
        obj&.foo(1)&.bar(2)&.zoo

~~~
enkephalin
this is working just fine:

    
    
      nil&.+(3)&.+(5)&.-(7)

------
glasz
nobody noticed the bytecode section?

~~~
nchelluri
yes. care to elaborate? first thing that came to mind was "APC-style"
([https://secure.php.net/manual/en/intro.apc.php](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.

~~~
cheald
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.

------
igouy
ruby-2.3.0.tar.bz2 does not seem to have

    
    
        /ruby-2.3.0/bin/ruby
    
    ?

~~~
dbailey5
Its the source, you have to compile it yourself. Checkout the readme :)

~~~
igouy
Thanks for the reminder.

