![]() |
Help, Ruby 1.8.6-p287 broke my "use" library and I don't know why
Hi everyone,
I need help! I've got a library called "use" that let's you mixin methods from modules in a fine-grained fashion. Unfortunately, something broke it between Ruby 1.8.6-p111 and Ruby 1.8.6-p287. It may have something to do with the way I autogenerate some methods in the windows-api library, as simple cases still work fine, but I'm not sure how or why. Here's some sample code: # test.rb require 'use' require 'windows/path' require 'windows/msvcrt/io' class Foo use Windows::Path use Windows::MSVCRT::IO, :tmpfile def initialize p PathIsRoot("C:\\") p tmpfile() end end Foo.new Using Ruby 1.8.6-p111 I get: true 2009464032 Using Ruby 1.8.6-p287 I get: (eval):3:in `PathIsRoot': uninitialized constant Class::PathIsRoot (NameError) from test.rb:10:in `initialize' from test.rb:15:in `new' from test.rb:15 What the heck happened between p 111 and p 287? Below is the full source for use.rb. Regards, Dan class Class # The version of the 'use' library USE_VERSION = '1.2.2' # Allows you to include mixins in a fine grained manner. Instead of # including all methods from a given module, you can instead mixin # only those methods you want through a combination of the :include, # :exclude, and :alias options. # # Examples: # # # Defines a 'bar' and 'baz' method # module Foo # def bar # "hello" # end # def baz # "world" # end # end # # # Defines a 'bar', 'blah', and 'zap' methods # module Test # def bar # "goodbye" # end # def blah # "new york" # end # def zap # "zap" # end # end # # # From the Foo module, only mixin the 'bar' method. From the Test # # module exclude the 'bar' and 'zap' methods. # class Zap # use Foo, :bar # use Test, :exclude => [:bar, :zap] # end # # z = Zap.new # # z.bar # => "hello" # z.baz # => NoMethodError - wasn't mixed in # z.zap # => NoMethodError - wasn't mixed in # z.blah # =>"new york" # # # Alias a method on the fly # class MyKlass # use Foo :alias => {:bar, :test} # end # # m = MyKlass.new # m.test # => "hello" # m.bar # => NoMethodError - was aliased to 'test' # # If no options follow the module name this method is identical # to a standard include. # def use(*args) valid_keys = %w/include exclude alias/ excluded = [] included = [] aliased = [] mod = args.shift.clone # If no arguments follow the mod name, treat as a standard include if args.empty? included.concat(mod.instance_methods) end m = Module.new args.each{ |arg| if arg.kind_of?(Hash) arg.each{ |key, val| case key.to_s when "include" if val.respond_to?(:each) val.each{ |arg| included.push(arg.to_s) } else included.push(val.to_s) end when "exclude" if val.respond_to?(:each) val.each{ |arg| excluded.push(arg.to_s) } else excluded.push(val.to_s) end when "alias" aliased.push(val) else raise "invalid key '#{key}'" end } else included.push(arg.to_s) end } unless included.empty? || excluded.empty? err = "you cannot include and exclude in the same statement" raise ArgumentError, err end imethods = mod.instance_methods # Remove excluded methods unless excluded.empty? (imethods & excluded).each{ |meth| mod.module_eval{ remove_method(meth) } } end # Alias methods aliased.each{ |pair| pair.each{ |old, new| included.push(old) # Aliased methods automatically included mod.module_eval{ alias_method(new, old) remove_method(old) } } } # Remove methods not specifically included. The rescue was needed # for cases where a module included another module. Also, don't # remove methods that already exist unless specifically included. unless included.empty? (imethods - included).each{ |meth| if superclass.instance_methods.include?(meth) if included.include?(meth) mod.module_eval{ undef_method(meth) rescue nil } else mod.module_eval{ remove_method(meth) rescue nil } end else mod.module_eval{ undef_method(meth) rescue nil } end } end m.module_eval{ include mod } # Raise a warning if methods are shadowed (in $VERBOSE mode) if $VERBOSE imethods = instance_methods(true) m.instance_methods.each{ |meth| next unless imethods.include?(meth) warn "method '#{meth}' aliased, shadows old '#{meth}'" } end include m end end |
Re: Help, Ruby 1.8.6-p287 broke my "use" library and I don't knowwhy
Hi,
At Sun, 28 Sep 2008 05:42:59 +0900, Daniel Berger wrote in [ruby-talk:316199]: > It may have something to do with the way I autogenerate some methods in > the windows-api library, as simple cases still work fine, but I'm not > sure how or why. Reproduced with: module X XXX = 1 def xxx XXX end end class Foo use X end Foo.new.xxx And worked fine with the SVN 1.8 branch head. -- Nobu Nakada |
Re: Help, Ruby 1.8.6-p287 broke my "use" library and I don't knowwhy
Hi Dan --
On Sun, 28 Sep 2008, Daniel Berger wrote: > Hi everyone, > > I need help! > > I've got a library called "use" that let's you mixin methods from modules in > a fine-grained fashion. Unfortunately, something broke it between Ruby > 1.8.6-p111 and Ruby 1.8.6-p287. > > It may have something to do with the way I autogenerate some methods in the > windows-api library, as simple cases still work fine, but I'm not sure how or > why. Do you have a non-Windows example where it does this? David -- Rails training from David A. Black and Ruby Power and Light: Intro to Ruby on Rails January 12-15 Fort Lauderdale, FL Advancing with Rails January 19-22 Fort Lauderdale, FL * * Co-taught with Patrick Ewing! See http://www.rubypal.com for details and updates! |
Re: Help, Ruby 1.8.6-p287 broke my "use" library and I don't know why
On Sep 27, 3:14*pm, "David A. Black" <dbl...@rubypal.com> wrote:
> Hi Dan -- > > On Sun, 28 Sep 2008, Daniel Berger wrote: > > Hi everyone, > > > I need help! > > > I've got a library called "use" that let's you mixin methods from modules in > > a fine-grained fashion. Unfortunately, something broke it between Ruby > > 1.8.6-p111 and Ruby 1.8.6-p287. > > > It may have something to do with the way I autogenerate some methods inthe > > windows-api library, as simple cases still work fine, but I'm not sure how or > > why. > > Do you have a non-Windows example where it does this? Nobu's example summarizes the problem: require 'use' module X XXX = 1 def xxx XXX end end class Foo use X end Foo.new.xxx Regards, Dan |
Re: Help, Ruby 1.8.6-p287 broke my "use" library and I don't knowwhy
David A. Black wrote:
> Hi -- > > On Sun, 28 Sep 2008, Daniel Berger wrote: > >> On Sep 27, 3:14?pm, "David A. Black" <dbl...@rubypal.com> wrote: >>> Hi Dan -- >>> >>> On Sun, 28 Sep 2008, Daniel Berger wrote: >>>> Hi everyone, >>> >>>> I need help! >>> >>>> I've got a library called "use" that let's you mixin methods from >>>> modules in >>>> a fine-grained fashion. Unfortunately, something broke it between Ruby >>>> 1.8.6-p111 and Ruby 1.8.6-p287. >>> >>>> It may have something to do with the way I autogenerate some methods >>>> in the >>>> windows-api library, as simple cases still work fine, but I'm not >>>> sure how or >>>> why. >>> >>> Do you have a non-Windows example where it does this? >> >> Nobu's example summarizes the problem: >> >> require 'use' >> >> module X >> XXX = 1 >> def xxx >> XXX >> end >> end >> >> class Foo >> use X >> end >> >> Foo.new.xxx > > For what it's worth, here's an even simpler example, not involving > your "use" library: > > class Class > def myuse(mod) > include mod.clone > end > end > > module X > XXX = 1 > def xxx > XXX > end > end > > class Foo > myuse X > end > > Foo.new.xxx > > This works with p230 but not p287. I guess it has to do with module > cloning and constants, but I haven't tracked it down beyond that. Thanks for that David. I was wondering what the underlying issue was. Regards, Dan |
| All times are GMT. The time now is 04:31 PM. |
Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.