

Ruby 2.1 In Detail - timblair
http://globaldev.co.uk/2014/05/ruby-2-1-in-detail/

======
losvedir
Funny! I actually came across this article yesterday when trying to look into
the current state of Ruby's global method cache. I had a question about the
write-up, so maybe I can ask it here!

The page says:

> _This is now no longer an issue, Ruby 2.1 uses a method cache based on the
> class hierarchy, invalidating the cache for only the class in question and
> any subclasses._

How does this work with an _instance_ of a class? Does it invalidate only that
instance's method cache, or all instances in that class? If I do DCI-style:

    
    
       @user.extend(PasswordConfirmable)
    

Does that blow away the cache for all User instances, or just that one?

~~~
jxf
Just that one. The "class" that the method is attached to here is the
metaclass of `@user`.

That class is below `User` in the hierarchy:

    
    
        class User; def foo; "foo"; end; end
        # => :foo
        module M; def bar; "bar"; end; end
        # => :bar
    
        u = User.new
        # => #<User:0x007f2e1abc9e00>
        u.extend M
        # => #<User:0x007f2e1abc9e00>
        
        u.singleton_class.ancestors
        # => [#<Class:#<User:0x007f2e1abc9e00>>,
         M,
         User,
         Object,
         PP::ObjectMixin,
         Kernel,
         BasicObject]

~~~
rubiquity
Your example isn't conclusive that what you're saying is true. Your example is
just showing that the extended module only appears in the instance's singleton
class, this has nothing to do with method cache. It's how the method cache is
implemented that matters. The new method caching changes can't be seen from
user code.

I'm curious as to whether the ruby-core team implemented method caches for
every Object in the system (eg: every instance of User would then have its own
method cache because they all would have their own singleton classes) or just
objects that are instances of the Class class. I seem to doubt that the former
happened because it seems like it would be expensive to maintain a cache for
_every_ object, that means a normal Rails request that generates 65,000
strings would all have their own method caches. Only instances of the Class
class having their own method caches sounds more reasonable from a performance
standpoint to me.

For what it's worth, I've been trying to get an answer about this from a ruby-
core member, although my attempts have been quite lazy through Twitter.

~~~
jxf
> Your example is just showing that the extended module only appears in the
> instance's singleton class, this has nothing to do with method cache. It's
> how the method cache is implemented that matters.

The method cache works by invalidating anything below the class(es) whose
methods have changed on the ancestor chain.

You're right that it can't be seen from user code, but if you take the
implementers at their word about how it works, then this should be a perfectly
convincing demonstration.

Or, if you don't believe me, read the source yourself:

[https://github.com/ruby/ruby/blob/ba6b0acdb6c371f9f7150bed6f...](https://github.com/ruby/ruby/blob/ba6b0acdb6c371f9f7150bed6f555c7f34fe3781/vm_insnhelper.c#L823-L841)

[https://github.com/ruby/ruby/blob/1aa54bebaf274bc08e72f9ad38...](https://github.com/ruby/ruby/blob/1aa54bebaf274bc08e72f9ad3854c7ad592c344a/vm_method.c#L78-L94)

The part that clears the class hierarchy is here:

[https://github.com/ruby/ruby/blob/1aa54bebaf274bc08e72f9ad38...](https://github.com/ruby/ruby/blob/1aa54bebaf274bc08e72f9ad3854c7ad592c344a/vm_method.c#L56-L61)

Alternatively, see Koichi's presentation at RubyKaiga:

[http://www.atdot.net/~ko1/activities/RubyKaigi2013-ko1.pdf](http://www.atdot.net/~ko1/activities/RubyKaigi2013-ko1.pdf)

------
ollysb
There's some great little improvements in there, to_h, required keywords and
being able to decorate methods are all things that I regularly want. They're
really making good on their philosophy of optimising for developer happiness
:)

------
grey-area
Hurray, they fixed a little bug I reported: Dir glob returns composed
characters. I hit this bug a year or so ago when processing files on OS X.

Thanks to the Ruby team for all the hard work on 2.1, it looks like there's a
lot of little changes in there.

------
anonova
Does Ruby truly follow semantic versioning now? I still see the patch version.

    
    
        $ ruby -v
        ruby 2.1.1p76 (2014-02-24 revision 45161) [x86_64-darwin13.0]

~~~
chrisseaton
No they don't exactly follow semantic versioning, which is as useful as not
following semantic versioning at all.

Specifically, I believe they're planning on breaking API compatibility within
major version numbers.

~~~
steveklabnik
> Specifically, I believe they're planning on breaking API compatibility
> within major version numbers.

Yes. Full details: [https://www.ruby-lang.org/en/news/2013/12/21/semantic-
versio...](https://www.ruby-lang.org/en/news/2013/12/21/semantic-versioning-
after-2-1-0/)

~~~
adamors
> Semantic Versioning starting with Ruby 2.1.0

> MINOR: increased every christmas, may be API incompatible

That is not semantic versioning.

~~~
steveklabnik
I know :'(

