What's New in Ruby 2.1 [pdf]
atdot.net
atdot.net
Ruby 2.1 introduces a generational garbage collector, this divides all objects into young and old generations. A regular GC run will only look at the young generation, with the old being collected less frequently. An object is promoted to the old generation when it survives a young generation run.
If you have objects in the old generation referring objects in the young generation, but you're only looking at the young generation it may seem like an object doesn't have any references, and you might incorrectly GC an in-use object. Write barriers prevent this by adding old generation objects to a 'remember set' when they are modified to refer to a young generation object (eg old_array.push(young_string)). This 'remember set' is then taken in to account when collecting the young generation.
Most generational garbage collectors need these write barriers on all objects, but with the many 3rd party C extensions available for Ruby this isn't possible, so a workaround was devised whereby objects that aren't write barrier protected won't ever be promoted to the old generation. This isn't ideal as you won't get the full benefit of the generational GC, but it does maximise backwards compatibility.
http://ruby-doc.org/stdlib-2.1.0/libdoc/objspace/rdoc/Object...
I wrote a little about them here: http://globaldev.co.uk/2013/03/ruby-2-0-0-in-detail/#id6
I can understand needing to freeze an existing String, but you can do that with Object#freeze, but a literal syntax seems to overlap with the usage of Symbols. The only benefit I can think of is not needing to use Symbol#to_s when working alongside strings.
I'm not saying frozen strings are not useful, because they can be after taking in some input/params to work with/store, but a literal syntax seems extremely edge-case-y. Now instead of "foo".freeze it's "foo"f, but how frequently will that save you time/trouble?
The bigger implication is that slides 23/24 shows that immutable strings and symbols will share their heap locations, if I'm reading the diagrams correctly, but have different object_ids.
This seems a bit bewildering and focused on micro-optimization, which is not the mental model I have in mind when I'm coding in a very high level language. It's also blurring the semantic difference between Symbols and Strings.
Worse, it seems to break the model of "interact with objects by sending messages", where you send a message using
<object>.<message>
Is "foo"f _not_ sending a message? If so, then what is it doing? If yes, then why new syntax?Prior to 2.1:
def foo
"bar".freeze
end
does these things every time `foo` is called:1. copies the characters 'b', 'a', and 'r' into a mutable string
2. sends the message `freeze` to the new string, which...
3. marks the string as frozen.
In 2.1 `"bar".freeze` is equivalent to `"bar"f`, which will not make a copy every time `foo` is called. See https://bugs.ruby-lang.org/issues/8579 for more discussion.
https://www.ruby-lang.org/en/news/2013/11/22/ruby-2-1-0-prev...
Thanks for the heads-up!
(I agree that it's a weird, low level detail to have to think about.)
Yes.
> Why don't I constantly see warnings against using String#intern the way I do about list_to_atom/1?
Because leaking memory over time is pretty much the natural state of being for Ruby apps. Periodic process restarts are culturally A-OK. Leaking symbols are likely to be the least of your perf problems.
But even in Erlang, the issue is only calling an interning operation on untrusted user data. In most real word use cases, you'll leak until a constant limit, which is probably no big deal. However, I've seen many Rails vulnerable to trivial DOS attacks by sending 1MB of random nonsense in a field known to be .to_sym-ed
private static void def main(args) ...; endthe "private" keyword already takes a symbol for a method name to privatize, so in this case the return of "def methodname(args); end" is ":methodname" which then gets passed to "private" and everything magically works.
def foo(bar:)
Named args with defaults solved one half of the problem we'd been solving with the "options hash"; now that's the second half. Can't wait!Optional typing would be very useful for big Ruby apps.
What is it with the ruby debugger? It has always been problematic for me.
There are pry wrappers for byebug - https://github.com/deivid-rodriguez/pry-byebug - maybe that'll work?