[rspec-users] class << self considered harmful... really?

Brian Takita brian.takita at gmail.com
Sat Nov 29 14:19:35 EST 2008


On Fri, Nov 28, 2008 at 1:17 PM, Student <blogger at pierian-spring.net> wrote:
> Performance is one of those nasty things that can go from being a non-
> issue to THE issue (next to correctness) in the blink of an eye.  I am
> curious, however.  How much total performance difference did this
> change make?  I'm betting <1%.
Yeah, this seems like premature optimization, if this were the only
reason. Rspec does not call class << foo nearly 10000 times.
Even if rspec did use class << foo 10000 times (each of which can
define multiple methods), it would make 0.x seconds of a difference in
the worst case (each class << object block only defines one method)
and 0.0x seconds difference in the best case (one object with 10000
methods defined in it).

http://gist.github.com/30285

Here are my numbers where method is defined on a single object 10000 times:
http://gist.github.com/raw/30285/a1731a82a0a59ec127b799ddb3b22763e9d06dd4

Heres another interesting benchmark where method is defined on 10000
objects 1 time:
http://gist.github.com/raw/30285/a99305dbeef2aed8453add68a5197cff3418bb69

>
> Nathan
>
> David Chelimsky wrote:
>> On Thu, Nov 27, 2008 at 8:17 PM, Mark Wilden <mark at mwilden.com> wrote:
>>> On Thu, Nov 27, 2008 at 5:57 PM, Brian Takita <brian.takita at gmail.com>
>>> wrote:
>>>> I'm wondering if this is a discussion about taste.
>>> I think you're right. I've been using the 'def self.foo' style in various
>>> languages for almost 20 years, so of course it feels more natural to me.
>>> These languages (except for Smalltalk) had nowhere near the metaprogramming
>>> capability nor 'objects all the way down'-ness of Ruby, and 'class << self'
>>> is one of those things.
>>>
>>> ///ark
>>
>> FWIW, the blog that led to this discussion suggested a performance
>> impact as well. As RSpec has gotten dinged for being slower than
>> alternatives, that interested me, so I did a little experiment def'ing
>> methods 10k times with def self.method and class << self; def method
>> ....
>>
>> def self.method ran an average of 10% faster.
>>
>> Based on just that, I've all but eliminated class << self from rspec in git.
>>
>> Crazy?
>
>
> On Nov 25, 8:52 am, "David Chelimsky" <dchelim... at gmail.com> wrote:
>> On Tue, Nov 25, 2008 at 8:39 AM, Zach Dennis <zach.den... at gmail.com> wrote:
>> > On Tue, Nov 25, 2008 at 9:38 AM, Zach Dennis <zach.den... at gmail.com> wrote:
>> >> On Tue, Nov 25, 2008 at 8:41 AM, Matt Wynne <m... at mattwynne.net> wrote:
>> >>> Sorry, I know this is off-topic, but I'd really like to know what the
>> >>> revered ruby-hackers who read this list think.
>>
>> >>> See
>> >>>http://ozmm.org/posts/class__self_is_harmful.html
>>
>> >>> I have adopted class << self, partly from reading RSpec and Cucumber's code
>> >>> as I learn Ruby. I personally think of class methods (or 'static' methods)
>> >>> as being in a kind of 'holding pen' waiting to be factored off onto a proper
>> >>> class of their own, so I rather like the clear way you can group them in a
>> >>> 'nameless' metaclass ready for the exit door.
>>
>> >>> I also really like the clarity of seeing the invisible metaclass for what it
>> >>> is.
>>
>> >>> What do people think? How can this be harmful?
>>
>> > I forgot to add it is considered harmful because it can so easily be
>> > abused and make readability of the code very difficult to understand.
>> > Especially when doing meta-meta programming. :)
>>
>> >> I think the issue is that people are using class << self to access the
>> >> virtual class when they don't need it. I've seen code where you have
>> >> to scroll to see all of the methods implemented inside of class <<
>> >> self. Adding methods to a virtual class does make method dispatching
>> >> in ruby less efficient, but I don't think enough to render it
>> >> non-usable.
>>
>> >> The virtual class of an object (class or instance alike) gives you the
>> >> ability to modify the object in ways that a simple class method
>> >> usually does not allow. For example, if you want to break down a class
>> >> method into a couple of methods, but you don't want to support all of
>> >> the methods as a public API. Here you can use class << self to
>> >> privately scope some of those helper methods that you just decomposed.
>>
>> >> My rule of thumb is to use it when I can't easily achieve the same
>> >> result using other mechanisms, but not to use it just cause'.
>>
>> One thing Chris points out in his blog is that 'def self.method_name'
>> is perfectly fine, and that it makes refactoring easier. My experience
>> is different, because I'm often searching for methods with 'dev
>> method_name' - this is actually one of the reasons I have preferred
>> 'class << self'.
>>
>> That said, I'm all for speeding things up where we can, so I'll be
>> looking into this in rspec. I just found 22 uses of 'class << self' in
>> rspec. Sometime soon I'll see how many of them I feel I can get rid
>> of.
>>
>> Cheers,
>> David
>>
>>
>>
>>
>>
>> >> --
>> >> Zach Dennis
>> >>http://www.continuousthinking.com
>> >>http://www.mutuallyhuman.com
>>
>> > --
>> > Zach Dennis
>> >http://www.continuousthinking.com
>> >http://www.mutuallyhuman.com
>> > _______________________________________________
>> > rspec-users mailing list
>> > rspec-us... at rubyforge.org
>> >http://rubyforge.org/mailman/listinfo/rspec-users
>>
>> _______________________________________________
>> rspec-users mailing list
>> rspec-us... at rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users
>


More information about the rspec-users mailing list