---1400102478-1905724411-1150330653620 Content-Type: MULTIPART/MIXED; BOUNDARY="-1400102478-1905724411-1150330653=:4620" This message is in MIME format. The first part should be readable text, while the remaining parts are likely unreadable without MIME-aware tools. ---1400102478-1905724411-1150330653620 Content-Type: TEXT/PLAIN; CHARSET=US-ASCII; FORMAT=flowed Content-ID: <Pine.LNX.4.62.0606141817411.4620 / harp.ngdc.noaa.gov> On Thu, 15 Jun 2006, Daniel Schierbeck wrote: hi daniel- > I can of course only speak for myself, but I'm not fond of the idea of > reserving constant names when it's really not needed -- "class extension", > as it seemingly has come to be named, should be handled internally, within > the module that defines such an extension. Even if the ClassMethods and > InstanceMethods modules are private, they would still clutter the namespace. > By using anonymous modules in instance variables you avoid collisions (not > completely of course.) > > Furthermore, I feel that it's redundant to have an entire "child" module for > the instance methods. indeed. read the code though, it's not needed - it's just for symmtry. > Not that the implementation is bad at all; I just don't think it's > streamlined enough to make it to the core, although that obviously isn't my > call to make. here's my complaint against any non-module based solution: it wildly violates POLS due to the change in scoping. i'm not saying it can't be done, but read over these tests/demos carefully and you'll see it's not quite as straightforward as you're suggesting - espcially if you want 'normal' class method definition semantics. i think you may be able to work around some of these issues, but some are part of ruby. harp:~ > ruby a.rb _______________________________________________________________________________ recursive inclusion : meta_module _______________________________________________________________________________ a.rb:140:in `included': stack level too deep (SystemStackError) from a.rb:140:in `included' from a.rb:9 from a.rb:197:in `show' from a.rb:194:in `show' from a.rb:4 _______________________________________________________________________________ recursive inclusion : mixable _______________________________________________________________________________ success _______________________________________________________________________________ double inclusion : meta_module _______________________________________________________________________________ a.rb:140:in `append_features': cyclic include detected (ArgumentError) from a.rb:140:in `included' from a.rb:37 from a.rb:197:in `show' from a.rb:194:in `show' from a.rb:23 _______________________________________________________________________________ double inclusion : mixable _______________________________________________________________________________ success _______________________________________________________________________________ namespace pollution : meta_module _______________________________________________________________________________ a.rb:73: N polluted! (RuntimeError) from a.rb:197:in `show' from a.rb:194:in `show' from a.rb:60 _______________________________________________________________________________ namespace pollution : mixable _______________________________________________________________________________ success _______________________________________________________________________________ constant scoping : meta_module _______________________________________________________________________________ a.rb:104:in `const_get': uninitialized constant #<Module:0xb75ccc50>::C (NameError) from a.rb:104 from a.rb:131:in `meta_module' from a.rb:102 from a.rb:197:in `show' from a.rb:194:in `show' from a.rb:100 _______________________________________________________________________________ constant scoping : mixable _______________________________________________________________________________ success harp:~ > cat a.rb # # recursive inclusion # show('recursive inclusion', :meta_module){ module M meta_module{ def foo() :foo end } include M end } show('recursive inclusion', :mixable){ module M module ClassMethods def foo() :foo end end mixin M end } # # double inclusion # show('double inclusion', :meta_module){ module M meta_module{ def foo() :foo end } end module N meta_module{ def bar() :bar end } include M end class C include M include N end } show('double inclusion', :mixable){ module M module ClassMethods def foo() :foo end end end module N module ClassMethods def bar() :bar end end mixin M end class C mixin M mixin N end } # # namespace pollution # show('namespace pollution', :meta_module){ module N meta_module{ def foo() :foo end } end module M include N meta_module{ def bar() :foo end # defined in N! } end if N.respond_to? 'bar' raise 'N polluted!' else true end } show('namespace pollution', :mixable){ module N module ClassMethods def foo() :foo end end end module M mixin N module ClassMethods def bar() :foo end end end if N.respond_to? 'bar' raise 'N polluted!' else true end } # # constant scoping # show('constant scoping', :meta_module){ module N meta_module{ C rue const_get :C } end true } show('constant scoping', :mixable){ module N module ClassMethods C rue const_get :C end end true } BEGIN { # # define two impls of class method mixin # META_MODULE_IMPL ambda { class Module def meta_module(&block) @meta_module || odule.new @meta_module.module_eval(&block) extend(@meta_module) @meta_module end def included(mod) mod.extend(@meta_module || odule.new) if mod.kind_of? Module if mod.instance_variables.include? "@meta_module" other_meta_module od.instance_variable_get(:@meta_module) other_meta_module.send(:include, @meta_module) else mod.instance_variable_set(:@meta_module, @meta_module) end end end end } MIXABLE_IMPL ambda { module Mixable Mixin ambda do |this, other| cm his.const_get 'ClassMethods' rescue nil im his.const_get 'InstanceMethods' rescue nil other.extend cm if cm other.module_eval{ include im if im extend RecursiveMixin } end module RecursiveMixin def included other Mixin[self, other] super end end extend RecursiveMixin end class Object def mixin other sc lass << self self end sc.module_eval{ mixin other } end end class Module def mixin other other.module_eval{ include Mixable } unless Mixable > other include other end end } # # demonstrate implications of two implimentations of class method mixin # def show label, which, &code div _' * 79 puts div puts "#{ label } : #{ which }" puts div impl bject.const_get(which.to_s.upcase << '_IMPL') fork { STDOUT.sync TDERR.sync rue impl.call ret ode.call puts(ret ? 'success' : 'failed') } Process.wait ensure 2.times{ puts } end } regards. -a -- suffering increases your inner strength. also, the wishing for suffering makes the suffering disappear. - h.h. the 14th dali lama ---1400102478-1905724411-1150330653620 Content-Type: TEXT/PLAIN; CHARSET=US-ASCII; NAME=a.rb Content-Transfer-Encoding: BASE64 Content-ID: <Pine.LNX.4.62.0606141817330.4620 / harp.ngdc.noaa.gov> Content-Description: Content-Disposition: ATTACHMENT; FILENAME=a.rb Iw0KIyByZWN1cnNpdmUgaW5jbHVzaW9uDQojDQogIHNob3coJ3JlY3Vyc2l2 ZSBpbmNsdXNpb24nLCA6bWV0YV9tb2R1bGUpew0KICAgIG1vZHVsZSBNDQog ICAgICBtZXRhX21vZHVsZXsNCiAgICAgICAgZGVmIGZvbygpIDpmb28gZW5k DQogICAgICB9DQogICAgICBpbmNsdWRlIE0NCiAgICBlbmQNCiAgfQ0KICBz aG93KCdyZWN1cnNpdmUgaW5jbHVzaW9uJywgOm1peGFibGUpew0KICAgIG1v ZHVsZSBNDQogICAgICBtb2R1bGUgQ2xhc3NNZXRob2RzDQogICAgICAgIGRl ZiBmb28oKSA6Zm9vIGVuZA0KICAgICAgZW5kDQogICAgICBtaXhpbiBNDQog ICAgZW5kDQogIH0NCiMNCiMgZG91YmxlIGluY2x1c2lvbg0KIw0KICBzaG93 KCdkb3VibGUgaW5jbHVzaW9uJywgOm1ldGFfbW9kdWxlKXsNCiAgICBtb2R1 bGUgTQ0KICAgICAgbWV0YV9tb2R1bGV7DQogICAgICAgIGRlZiBmb28oKSA6 Zm9vIGVuZA0KICAgICAgfQ0KICAgIGVuZA0KICAgIG1vZHVsZSBODQogICAg ICBtZXRhX21vZHVsZXsNCiAgICAgICAgZGVmIGJhcigpIDpiYXIgZW5kDQog ICAgICB9DQogICAgICBpbmNsdWRlIE0NCiAgICBlbmQNCiAgICBjbGFzcyBD DQogICAgICBpbmNsdWRlIE0NCiAgICAgIGluY2x1ZGUgTg0KICAgIGVuZA0K ICB9DQogIHNob3coJ2RvdWJsZSBpbmNsdXNpb24nLCA6bWl4YWJsZSl7DQog ICAgbW9kdWxlIE0NCiAgICAgIG1vZHVsZSBDbGFzc01ldGhvZHMNCiAgICAg ICAgZGVmIGZvbygpIDpmb28gZW5kDQogICAgICBlbmQNCiAgICBlbmQNCiAg ICBtb2R1bGUgTg0KICAgICAgbW9kdWxlIENsYXNzTWV0aG9kcw0KICAgICAg ICBkZWYgYmFyKCkgOmJhciBlbmQNCiAgICAgIGVuZA0KICAgICAgbWl4aW4g TQ0KICAgIGVuZA0KICAgIGNsYXNzIEMNCiAgICAgIG1peGluIE0NCiAgICAg IG1peGluIE4NCiAgICBlbmQNCiAgfQ0KIw0KIyBuYW1lc3BhY2UgcG9sbHV0 aW9uIA0KIw0KICBzaG93KCduYW1lc3BhY2UgcG9sbHV0aW9uJywgOm1ldGFf bW9kdWxlKXsNCiAgICBtb2R1bGUgTg0KICAgICAgbWV0YV9tb2R1bGV7DQog ICAgICAgIGRlZiBmb28oKSA6Zm9vIGVuZA0KICAgICAgfQ0KICAgIGVuZA0K ICAgIG1vZHVsZSBNDQogICAgICBpbmNsdWRlIE4NCiAgICAgIG1ldGFfbW9k dWxlew0KICAgICAgICBkZWYgYmFyKCkgOmZvbyBlbmQgICMgZGVmaW5lZCBp biBOIQ0KICAgICAgfQ0KICAgIGVuZA0KICAgIGlmIE4ucmVzcG9uZF90bz8g J2JhcicNCiAgICAgIHJhaXNlICdOIHBvbGx1dGVkIScNCiAgICBlbHNlDQog ICAgICB0cnVlDQogICAgZW5kDQogIH0NCiAgc2hvdygnbmFtZXNwYWNlIHBv bGx1dGlvbicsIDptaXhhYmxlKXsNCiAgICBtb2R1bGUgTg0KICAgICAgbW9k dWxlIENsYXNzTWV0aG9kcw0KICAgICAgICBkZWYgZm9vKCkgOmZvbyBlbmQN CiAgICAgIGVuZA0KICAgIGVuZA0KICAgIG1vZHVsZSBNDQogICAgICBtaXhp biBODQogICAgICBtb2R1bGUgQ2xhc3NNZXRob2RzDQogICAgICAgIGRlZiBi YXIoKSA6Zm9vIGVuZA0KICAgICAgZW5kDQogICAgZW5kDQogICAgaWYgTi5y ZXNwb25kX3RvPyAnYmFyJw0KICAgICAgcmFpc2UgJ04gcG9sbHV0ZWQhJw0K ICAgIGVsc2UNCiAgICAgIHRydWUNCiAgICBlbmQNCiAgfQ0KDQojDQojIGNv bnN0YW50IHNjb3BpbmcNCiMNCiAgc2hvdygnY29uc3RhbnQgc2NvcGluZycs IDptZXRhX21vZHVsZSl7DQogICAgbW9kdWxlIE4NCiAgICAgIG1ldGFfbW9k dWxlew0KICAgICAgICBDID0gdHJ1ZSANCiAgICAgICAgY29uc3RfZ2V0IDpD DQogICAgICB9DQogICAgZW5kDQogICAgdHJ1ZQ0KICB9DQogIHNob3coJ2Nv bnN0YW50IHNjb3BpbmcnLCA6bWl4YWJsZSl7DQogICAgbW9kdWxlIE4NCiAg ICAgIG1vZHVsZSBDbGFzc01ldGhvZHMNCiAgICAgICAgQyA9IHRydWUgDQog ICAgICAgIGNvbnN0X2dldCA6Qw0KICAgICAgZW5kDQogICAgZW5kDQogICAg dHJ1ZQ0KICB9DQoNCg0KDQoNCg0KQkVHSU4gew0KIw0KIyBkZWZpbmUgdHdv IGltcGxzIG9mIGNsYXNzIG1ldGhvZCBtaXhpbg0KIw0KICBNRVRBX01PRFVM RV9JTVBMID0gbGFtYmRhIHsNCiAgICBjbGFzcyBNb2R1bGUNCiAgICAgIGRl ZiBtZXRhX21vZHVsZSgmYmxvY2spDQogICAgICAgIEBtZXRhX21vZHVsZSB8 fD0gTW9kdWxlLm5ldw0KICAgICAgICBAbWV0YV9tb2R1bGUubW9kdWxlX2V2 YWwoJmJsb2NrKQ0KICAgICAgICBleHRlbmQoQG1ldGFfbW9kdWxlKQ0KICAg ICAgICBAbWV0YV9tb2R1bGUNCiAgICAgIGVuZA0KICAgICAgZGVmIGluY2x1 ZGVkKG1vZCkNCiAgICAgICAgbW9kLmV4dGVuZChAbWV0YV9tb2R1bGUgfHw9 IE1vZHVsZS5uZXcpDQogICAgICAgIGlmIG1vZC5raW5kX29mPyBNb2R1bGUN CiAgICAgICAgICBpZiBtb2QuaW5zdGFuY2VfdmFyaWFibGVzLmluY2x1ZGU/ ICJAbWV0YV9tb2R1bGUiDQogICAgICAgICAgICBvdGhlcl9tZXRhX21vZHVs ZSA9IG1vZC5pbnN0YW5jZV92YXJpYWJsZV9nZXQoOkBtZXRhX21vZHVsZSkN CiAgICAgICAgICAgIG90aGVyX21ldGFfbW9kdWxlLnNlbmQoOmluY2x1ZGUs IEBtZXRhX21vZHVsZSkNCiAgICAgICAgICBlbHNlDQogICAgICAgICAgICBt b2QuaW5zdGFuY2VfdmFyaWFibGVfc2V0KDpAbWV0YV9tb2R1bGUsIEBtZXRh X21vZHVsZSkNCiAgICAgICAgICBlbmQNCiAgICAgICAgZW5kDQogICAgICBl bmQNCiAgICBlbmQNCiAgfQ0KDQogIE1JWEFCTEVfSU1QTCA9IGxhbWJkYSB7 DQogICAgbW9kdWxlIE1peGFibGUNCiAgICAgIE1peGluID0gbGFtYmRhIGRv IHx0aGlzLCBvdGhlcnwNCiAgICAgICAgY20gPSB0aGlzLmNvbnN0X2dldCAn Q2xhc3NNZXRob2RzJyByZXNjdWUgbmlsDQogICAgICAgIGltID0gdGhpcy5j b25zdF9nZXQgJ0luc3RhbmNlTWV0aG9kcycgcmVzY3VlIG5pbA0KICAgICAg ICBvdGhlci5leHRlbmQgY20gaWYgY20NCiAgICAgICAgb3RoZXIubW9kdWxl X2V2YWx7DQogICAgICAgICAgaW5jbHVkZSBpbSBpZiBpbQ0KICAgICAgICAg IGV4dGVuZCBSZWN1cnNpdmVNaXhpbg0KICAgICAgICB9DQogICAgICBlbmQN CiAgICAgIG1vZHVsZSBSZWN1cnNpdmVNaXhpbiANCiAgICAgICAgZGVmIGlu Y2x1ZGVkIG90aGVyDQogICAgICAgICAgTWl4aW5bc2VsZiwgb3RoZXJdDQog ICAgICAgICAgc3VwZXINCiAgICAgICAgZW5kDQogICAgICBlbmQNCiAgICAg IGV4dGVuZCBSZWN1cnNpdmVNaXhpbg0KICAgIGVuZA0KICAgIGNsYXNzIE9i amVjdA0KICAgICAgZGVmIG1peGluIG90aGVyDQogICAgICAgIHNjID0gDQog ICAgICAgICAgY2xhc3MgPDwgc2VsZg0KICAgICAgICAgICAgc2VsZg0KICAg ICAgICAgIGVuZA0KICAgICAgICBzYy5tb2R1bGVfZXZhbHsgbWl4aW4gb3Ro ZXIgfQ0KICAgICAgZW5kDQogICAgZW5kDQogICAgY2xhc3MgTW9kdWxlDQog ICAgICBkZWYgbWl4aW4gb3RoZXINCiAgICAgICAgb3RoZXIubW9kdWxlX2V2 YWx7IGluY2x1ZGUgTWl4YWJsZSB9IHVubGVzcyANCiAgICAgICAgICBNaXhh YmxlID4gb3RoZXINCiAgICAgICAgaW5jbHVkZSBvdGhlcg0KICAgICAgZW5k DQogICAgZW5kDQogIH0NCiMNCiMgZGVtb25zdHJhdGUgaW1wbGljYXRpb25z IG9mIHR3byBpbXBsaW1lbnRhdGlvbnMgb2YgY2xhc3MgbWV0aG9kIG1peGlu DQojDQogIGRlZiBzaG93IGxhYmVsLCB3aGljaCwgJmNvZGUNCiAgICBkaXYg PSAnXycgKiA3OQ0KICAgIHB1dHMgZGl2DQogICAgcHV0cyAiI3sgbGFiZWwg fSA6ICN7IHdoaWNoIH0iDQogICAgcHV0cyBkaXYNCiAgICBpbXBsID0gT2Jq ZWN0LmNvbnN0X2dldCh3aGljaC50b19zLnVwY2FzZSA8PCAnX0lNUEwnKQ0K ICAgIGZvcmsgeyANCiAgICAgIFNURE9VVC5zeW5jID0gU1RERVJSLnN5bmMg PSB0cnVlDQogICAgICBpbXBsLmNhbGwNCiAgICAgIHJldCA9IGNvZGUuY2Fs bCANCiAgICAgIHB1dHMocmV0ID8gJ3N1Y2Nlc3MnIDogJ2ZhaWxlZCcpDQog ICAgfQ0KICAgIFByb2Nlc3Mud2FpdA0KICBlbnN1cmUNCiAgICAyLnRpbWVz eyBwdXRzIH0NCiAgZW5kDQoNCg0KfQ0K ---1400102478-1905724411-1150330653620-- ---1400102478-1905724411-1150330653620--