diff --git a/lib/tins/concern.rb b/lib/tins/concern.rb index df279a4..05879f5 100644 --- a/lib/tins/concern.rb +++ b/lib/tins/concern.rb @@ -19,14 +19,41 @@ def append_features(base) end end + def prepend_features(base) + if base.instance_variable_defined?("@_dependencies") + base.instance_variable_get("@_dependencies") << self + false + else + return false if base < self + @_dependencies.each { |dep| base.send(:include, dep) } + super + base.extend const_get("ClassMethods") if const_defined?("ClassMethods") + base.class_eval(&@_prepended_block) if instance_variable_defined?("@_prepended_block") + Thread.current[:tin_concern_args] = nil + true + end + end + def included(base = nil, &block) if base.nil? + instance_variable_defined?(:@_included_block) and + raise StandardError, "included block already defined" @_included_block = block else super end end + def prepended(base = nil, &block) + if base.nil? + instance_variable_defined?(:@_prepended_block) and + raise StandardError, "prepended block already defined" + @_prepended_block = block + else + super + end + end + def class_methods(&block) modul = const_get(:ClassMethods) if const_defined?(:ClassMethods, false) unless modul diff --git a/tests/concern_test.rb b/tests/concern_test.rb index 6078522..71e2409 100644 --- a/tests/concern_test.rb +++ b/tests/concern_test.rb @@ -8,6 +8,10 @@ module AC $included = self end + prepended do + $prepended = self + end + def foo :foo end @@ -32,17 +36,37 @@ def baz2 end $included = nil + $prepended = nil class A include AC end - def test_concern + class B + prepend AC + end + + def test_concern_include a = A.new assert_equal A, $included assert_equal :foo, a.foo assert_equal :bar, A.bar assert_equal :baz1, A.baz1 assert_equal :baz2, A.baz2 + assert_raise(StandardError) do + AC.module_eval { included {} } + end + end + + def test_concern_prepend + a = B.new + assert_equal B, $prepended + assert_equal :foo, a.foo + assert_equal :bar, B.bar + assert_equal :baz1, B.baz1 + assert_equal :baz2, B.baz2 + assert_raise(StandardError) do + AC.module_eval { prepended {} } + end end end