Hacker News new | past | comments | ask | show | jobs | submit login
Ruby 2.1 In Detail (globaldev.co.uk)
112 points by timblair on May 6, 2014 | hide | past | favorite | 12 comments



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?


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]


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.


> 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/1aa54bebaf274bc08e72f9ad38...

The part that clears the class hierarchy is here:

https://github.com/ruby/ruby/blob/1aa54bebaf274bc08e72f9ad38...

Alternatively, see Koichi's presentation at RubyKaiga:

http://www.atdot.net/~ko1/activities/RubyKaigi2013-ko1.pdf


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 :)


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.


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]


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.


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


> Semantic Versioning starting with Ruby 2.1.0

> MINOR: increased every christmas, may be API incompatible

That is not semantic versioning.


I know :'(


The PATCH version is the "number of commits since last MINOR release (will be reset at 0 when releasing MINOR)" — https://www.ruby-lang.org/en/news/2013/12/21/semantic-versio...




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: