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