Project

General

Profile

Actions

Bug #9311

closed

module_function breaks on `singleton_class?`

Added by cheald (Chris Heald) over 10 years ago. Updated about 10 years ago.

Status:
Rejected
Assignee:
-
Target version:
-
ruby -v:
-
Backport:

Description

=begin
When trying to use Sass 3.3.0-rc2 with Rails 3.x, an error similar to the one below is produced:

[6] pry(Sass::Util)> Sass::Util.methods.grep /singleton_class/
=> [:singleton_class?, :singleton_class]
[7] pry(Sass::Util)> Sass::Util.method_function :singleton_class?
NoMethodError: undefined method `method_function' for Sass::Util:Module
from (pry):6:in `<module:Util>'

This is actually pretty trivially reproduced via:

2.1.0 :001 > module Foo
2.1.0 :002?>   methods.grep(/singleton/).each {|x| module_function x }
2.1.0 :003?>   end
NameError: undefined method `singleton_class?' for module `Foo'
        from (irb):2:in `module_function'
        from (irb):2:in `block in <module:Foo>'
        from (irb):2:in `each'
        from (irb):2:in `<module:Foo>'
        from (irb):1
        from /usr/local/rvm/rubies/ruby-2.1.0/bin/irb:11:in `<main>'

Now, Sass performs the following:

(Sass::Util.methods - Module.methods).each {|method| module_function method }

This succeeds if you don't include ActiveSupport, but ActiveSupport extends Class with the following:

class Class
  private
  def singleton_class?
    ancestors.first != self
  end
end

This causes singleton_class? to no longer show in the Module.methods list (I suspect because of the new method cache invalidation stuff?):

2.1.0 :001 > Module.methods.sort
 => [... :singleton_class, :singleton_class?, :singleton_method, :singleton_methods, :superclass, ...]
2.1.0 :002 > class Class
2.1.0 :003?>         private
2.1.0 :004?>         def singleton_class?
2.1.0 :005?>             ancestors.first != self
2.1.0 :006?>           end
2.1.0 :007?>       end
 => :singleton_class?
2.1.0 :008 > Module.methods.sort
 => [... :singleton_class, :singleton_method, :singleton_methods, :superclass, ...]

Since it's no longer in the Module.methods list, Sass attempts to module_function it and the whole thing blows up.

This is fixable in both Sass and ActiveSupport (which I'll file tickets for), but it feels like this is a Ruby bug. Doing something similar in 2.0 (which doesn't have singleton_class?) results in the following:

2.0.0p247 :001 > class Class
2.0.0p247 :002?>   private
2.0.0p247 :003?>   def singleton_class
2.0.0p247 :004?>     false
2.0.0p247 :005?>     end
2.0.0p247 :006?>   end
 => nil
2.0.0p247 :007 > module Foo
2.0.0p247 :008?>   module_function :singleton_class
2.0.0p247 :009?>   end
 => Foo
2.0.0p247 :010 > Foo.singleton_class
 => #<Class:Foo>

Which seems to work just fine.
=end


Files

bug9311-test.diff (568 Bytes) bug9311-test.diff tmm1 (Aman Karmani), 01/15/2014 11:50 PM
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0