Fetching latest commit…
Cannot retrieve the latest commit at this time.
|Failed to load latest commit information.|
Inheritable declarations for Ruby 1.8.6+ Author: Oleg Andreev <email@example.com> August-September, 2008. WTFPL License. == Trivial example from strokedb: module StrokeDB module NSURL include Declarations NO_NSURL = Object.new.freeze # Returns the most local NSURL or sets # nsulr in the current scope. def nsurl(nsurl = NO_NSURL) return self.nsurl=(nsurl) if nsurl != NO_NSURL inherited_declarations(:nsurl) do |all_nsurls| all_nsurls.first end end def nsurl=(nsurl) nsurl ? local_declarations_set(:nsurl, nsurl) : local_declarations_remove(:nsurl) end module Ours extend NSURL nsurl StrokeDB::STROKEDB_NSURL end module Theirs extend NSURL nsurl StrokeDB::DEFAULT_NSURL end Others = Theirs # useful const alias end end # usage: module MyModule extend NSURL nsurl "http://mymodule.com/" end MyModule.nsurl == "http://mymodule.com/" #=> true == Discussion We want to have module methods like has_many, validates_presence_of, after_save etc. Scenarios: Given a module A with such declarations, we include A into B, B has declaration methods and inherits the data from C. Given a class C with such declarations, we inherit D from C, D has declaration methods and inherits the data from C. Given a module A mixed in B, C we add declarations B and C get these declarations and inherit data from A. Given a class C with subclasses D1, D2 we add declarations D1, D2 get these declarations and inherit data from C. Given a module A mixed in B, C we modify declarations B and C inherit data from A. Given a class C with subclasses D1, D2 we modify declarations D1, D2 inherit data from C. Issue: when we have an hierarchy of plain modules and extend some of them with a DSL, all children must be extended with this DSL, right? Design choices: 1. keep lists of backreferences to children, this gonna waste the memory. 2. handle Module#method_missing in such way, that it searches ancestors for the desired method and extends the module with the missing declarations. 3. don't try to be THAT smart and simply tell user to "extend MyDSL" the module in case of such issue. We choose to be smartass (option 2). See Declarations::ModuleMethods.