From: "David A. Black" Date: 2008-05-02T12:24:32+09:00 Subject: Re: DSL - class-level methods that affect instances Hi -- On Fri, 2 May 2008, Ken Bloom wrote: > On Thu, 01 May 2008 19:55:45 -0500, Daniel Waite wrote: > >> Ken Bloom wrote: >>> On Thu, 01 May 2008 18:07:11 -0500, Daniel Waite wrote: >>> >>>> class C >>>> >>>> I have no idea how to break the barrier between class and instance. :( >>> >>> Use class variables (the @@ variety). >>> >>> class Translator::Base >>> def self.translate word, params >>> @@translations ||= {} >>> @@translations[word]=params[:to] >>> end >>> def translations >>> @@translations ||= {} >>> end >>> end >>> >>> class C < Translator::Base >>> translate 'a', :to => 'b' >>> translate 'c', :to => 'd' >>> end >>> >>> C.new.translations #=> {"a"=>"b", "c"=>"d"} >> >> That works! Except it shares translations across all subclasses. >> >> module Translator >> class Base >> >> def self.translate word, params >> @@translations ||= {} >> @@translations[word]=params[:to] >> end >> >> def translations >> @@translations ||= {} >> end >> >> end >> end >> >> class C < Translator::Base >> >> translate 'a', :to => 'b' >> translate 'c', :to => 'd' >> >> end >> >> class D < Translator::Base >> >> translate 'this', :to => 'that' >> >> end >> >> irb(main):028:0> c = C.new >> => # >> irb(main):029:0> c.translations >> => {"a"=>"b", "c"=>"d", "this"=>"that"} >> >> While I understand the behavior, its undesirable. I'm going to dust off >> Ruby for Rails... > > I couldn't remember why I didn't use @@ variables for another very > similar metaprogramming problem I had this week. Now you've reminded why. > > This version uses instance variables on the singleton class (which is > different from using @@ class variables) I wish that class variables were $$ instead of @@. They're really a kind of restricted global, and they have the same qualities of sprawl that globals do. The @@ always makes it look like they have some kind of kinship with instance variables, when in fact they're practically the opposite, in that they open up a shared space for storing state whereas instance variables specifically make it possible for objects to control state on an individual, private (give or take the fact that nothing is really private in Ruby) basis. David -- Rails training from David A. Black and Ruby Power and Light: INTRO TO RAILS June 9-12 Berlin ADVANCING WITH RAILS June 16-19 Berlin INTRO TO RAILS June 24-27 London (Skills Matter) See http://www.rubypal.com for details and updates!