public
Description: A mirror of the mephisto code-base
Homepage: http://mephistoblog.com/
Clone URL: git://github.com/halorgium/mephisto.git
Search Repo:
Enhance include_into with alias_method_chaining, closing #152
svenfuchs (author)
Wed Feb 06 13:27:46 -0800 2008
commit  d971d941df4351ad42b41896b3446f3d43fa9bcd
tree    8441e1a82843804d1bace8fcceea3aaedb60e87a
parent  7af009a57222f56ad33aa9527f323321ff39320e
...
3
4
5
6
 
7
8
9
10
11
12
13
...
11
12
13
 
 
 
 
 
 
 
 
 
 
 
14
15
 
16
17
 
18
19
20
21
 
22
23
24
25
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
27
28
...
3
4
5
 
6
7
8
9
10
11
12
13
...
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 
29
30
31
32
 
33
34
35
 
 
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
0
@@ -3,7 +3,7 @@
0
 
0
 Module.class_eval do
0
   # A hash that maps Class names to an array of Modules to mix in when the class is instantiated.
0
- @@class_mixins = {}
0
+ @@class_mixins = {} unless defined?(@@class_mixins)
0
   mattr_reader :class_mixins
0
 
0
   # Specifies that this module should be included into the given classes when they are instantiated.
0
0
0
0
0
@@ -11,18 +11,46 @@
0
   # module FooMethods
0
   # include_into "Foo", "Bar"
0
   # end
0
+ #
0
+ # You can also specify a hash to have your module's methods alias_method_chained to the target
0
+ # class' methods.
0
+ #
0
+ # module FooMethods
0
+ # include_into "Foo", :method => :feature
0
+ # end
0
+ #
0
+ # This will alias Foo#method to the newly included FooMethods#method_with_feature. The former
0
+ # method Foo#method will continue to be available as Foo#method_without_feature.
0
+ #
0
   def include_into(*klasses)
0
     klasses.flatten!
0
+ aliases = klasses.last.is_a?(Hash) ? klasses.pop : {}
0
     klasses.each do |klass|
0
- (@@class_mixins[klass] ||= []) << name.to_s
0
+ (@@class_mixins[klass] ||= []) << [name.to_s, aliases]
0
       @@class_mixins[klass].uniq!
0
     end
0
   end
0
-
0
+
0
   # add any class mixins that have been registered for this class
0
   def auto_include!
0
- mixins = @@class_mixins[name]
0
- send(:include, *mixins.collect { |name| name.constantize }) if mixins
0
+ if mixins = @@class_mixins[name]
0
+ mixins.each do |name, aliases|
0
+ include name.constantize
0
+ aliases.each { |args| alias_chain *args }
0
+ end
0
+ end
0
+ end
0
+
0
+ def alias_chain(target, feature)
0
+ (class << self; self end).class_eval <<-EOC, __FILE__, __LINE__
0
+ def method_added_with_#{target}_#{feature}(method)
0
+ if method == :#{target} && !method_defined?(:#{target}_without_#{feature})
0
+ alias_method_chain :#{target}, :#{feature}
0
+ end
0
+ method_added_without_#{target}_#{feature}(method)
0
+ end
0
+ alias_method_chain :method_added, :#{target}_#{feature}
0
+ EOC
0
   end
0
 end
0
 
...
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
0
@@ -1 +1,46 @@
0
+ENV['RAILS_ENV'] = 'test'
0
+RAILS_ROOT = File.join(File.dirname(__FILE__), '../../../../')
0
+
0
+require 'rubygems'
0
+require 'active_support'
0
+require 'test/unit'
0
+
0
+require File.join(File.dirname(__FILE__), '..', 'init.rb')
0
+
0
+module Chocolate
0
+ include_into 'Cookie', 'Coffee', :taste => :chocolate
0
+ def taste_with_chocolate; "#{self.class.name} with chocolate!" end
0
+end
0
+
0
+module Latte
0
+ include_into 'Coffee', 'Chai'
0
+end
0
+
0
+class Cookie
0
+ def taste; "just a #{self.class.name}" end
0
+end
0
+
0
+class Coffee
0
+ def taste; "just a #{self.class.name}" end
0
+end
0
+
0
+class Chai
0
+end
0
+
0
+class IncludeIntoTest < Test::Unit::TestCase
0
+ def test_module_should_be_included_to_given_classes
0
+ assert Cookie.included_modules.include?(Chocolate)
0
+ assert Coffee.included_modules.include?(Chocolate)
0
+ end
0
+
0
+ def test_methods_should_be_alias_chained_in_given_classes
0
+ assert_equal 'Cookie with chocolate!', Cookie.new.taste
0
+ assert_equal 'Coffee with chocolate!', Coffee.new.taste
0
+ end
0
+
0
+ def test_should_work_without_alias_option
0
+ assert Coffee.included_modules.include?(Latte)
0
+ assert Chai.included_modules.include?(Latte)
0
+ end
0
+end

Comments

    No one has commented yet.