contextr 0.1.1 → 0.1.9

Sign up to get free protection for your applications and to get access to all the features.
data.tar.gz.sig CHANGED
@@ -1,2 +1,2 @@
1
- j�@k�=�< I4c� 5���Q�`�ߵf�jsQ6a����aasL!�BE]̓�GqH䅘Q���s�/d�%y e,�M[E�,S�ꥇ�L5�����Ldo�����{ -�Y�����4���2G78�� rKx��_��%�6����)_b���/� e�]��/A�2�Z*^�
2
- �l��g��V��S1%#�@��wl����W�/�v
1
+ &�3��Q��<��o;\ؿ}0�`YG��(��%���z$9P�#��xj ���O�N 0*�kKK@\!�P�J3�ŵQ�S�$�Ds�K�f�/@� ��o0f��Sz)ٓ/?f#�&bD��186 oMGUHa��;��uq�{�:�f)���DW�ŭ��"5ǹ 7֦�m��X9s쬽��X�&�m
2
+ =����ȄJN�r��'���"kU{�v�nS̹��=��s#{>��㴯/<u�h�jQBN8(G ,z8
@@ -1,3 +1,11 @@
1
+ == 0.1.9 2007-11-30
2
+
3
+ * this is a review release
4
+ * documentation is not yet complete
5
+ * major changes
6
+ * documentation website
7
+ * again a new api
8
+
1
9
  == 0.1.1 2007-09-17
2
10
 
3
11
  * major changes
@@ -11,6 +11,7 @@ lib/contextr/core_ext.rb
11
11
  lib/contextr/core_ext/module.rb
12
12
  lib/contextr/core_ext/object.rb
13
13
  lib/contextr/event_machine.rb
14
+ lib/contextr/inner_class.rb
14
15
  lib/contextr/layer.rb
15
16
  lib/contextr/modules/mutex_code.rb
16
17
  lib/contextr/modules/unique_id.rb
@@ -23,10 +24,24 @@ setup.rb
23
24
  spec/contextr_spec.rb
24
25
  spec/spec.opts
25
26
  spec/spec_helper.rb
27
+ test/lib/example_test.rb
28
+ test/lib/literate_markaby_test.rb
29
+ test/lib/literate_maruku_test.rb
30
+ test/test_class_side.mkd
26
31
  test/test_class_side.rb
27
32
  test/test_contextr.rb
33
+ test/test_dynamic_scope.mkd
34
+ test/test_dynamic_scope.rb
35
+ test/test_dynamics.mkd
28
36
  test/test_dynamics.rb
37
+ test/test_hello_world.mkd
38
+ test/test_hello_world.rb
29
39
  test/test_helper.rb
40
+ test/test_introduction.mkd
30
41
  test/test_introduction.rb
42
+ test/test_layer_state.mkd
31
43
  test/test_layer_state.rb
44
+ test/test_meta_api.mkd
45
+ test/test_meta_api.rb
46
+ test/test_ordering.mkd
32
47
  test/test_ordering.rb
data/Rakefile CHANGED
@@ -107,8 +107,8 @@ task :website => [:website_generate, :website_upload, :publish_docs]
107
107
  desc 'Release the website and new gem version'
108
108
  task :deploy => [:check_version, :website, :release] do
109
109
  puts "Remember to create SVN tag:"
110
- puts "svn copy svn+ssh://#{rubyforge_username}@rubyforge.org/var/svn/#{PATH}/trunk " +
111
- "svn+ssh://#{rubyforge_username}@rubyforge.org/var/svn/#{PATH}/tags/REL-#{VERS} "
110
+ puts "svn copy svn+ssh://rubyforge.org/var/svn/#{PATH}/trunk " +
111
+ "svn+ssh://rubyforge.org/var/svn/#{PATH}/tags/contextr-#{VERS} "
112
112
  puts "Suggested comment:"
113
113
  puts "Tagging release #{CHANGES}"
114
114
  end
@@ -11,7 +11,8 @@ end
11
11
 
12
12
  # the basic library code
13
13
  %w{public_api class_methods layer
14
- event_machine core_ext version}.each { | file |
14
+ event_machine core_ext version
15
+ inner_class}.each { | file |
15
16
  require File.dirname(__FILE__) + "/contextr/#{file}" }
16
17
 
17
18
  unless Dynamic.variables.include?( :layers )
@@ -2,17 +2,17 @@ module ContextR # :nodoc:
2
2
  module ClassMethods # :nodoc:
3
3
  include MutexCode
4
4
 
5
- def const_missing(const_name)
6
- if const_name.to_s =~ /.*Layer$/
7
- self.const_set(const_name, Class.new(ContextR::Layer))
8
- else
9
- super
5
+ def stored_core_methods
6
+ @stored_core_methods ||= Hash.new do |hash, key|
7
+ hash[key] = Hash.new
10
8
  end
11
9
  end
12
10
 
13
- def stored_core_methods
14
- @stored_core_methods ||= Hash.new do | hash, key |
15
- hash[key] = Hash.new
11
+ def stored_module_definitions
12
+ @stored_module_definitions ||= Hash.new do |hash, key|
13
+ hash[key] = Hash.new do |hash, key|
14
+ hash[key] = Module.new
15
+ end
16
16
  end
17
17
  end
18
18
 
@@ -25,24 +25,22 @@ module ContextR # :nodoc:
25
25
  end
26
26
 
27
27
  def layers_as_classes
28
- constants.select { |l| l =~ /.+Layer$/ }.collect { |l|
29
- l.scan(/(.+)Layer/).first.first.underscore.to_sym
30
- }
28
+ @layers.values
31
29
  end
32
30
 
33
31
  def symbol_by_layer(lay)
34
- lay.to_s.gsub( /^ContextR::(.*)Layer$/, '\1' ).underscore.to_sym
32
+ @layers.index(lay)
35
33
  end
36
34
 
37
35
  def layer_by_symbol(sym)
38
- "ContextR::#{sym.to_s.camelize}Layer".constantize
36
+ @layers[sym] ||= ContextR::Layer.new
39
37
  end
40
38
 
41
39
  def call_methods_stack(stack, receiver, method_name, arguments, block)
42
40
  if stack.size == 1
43
41
  stack.pop.call(*arguments, &block)
44
42
  else
45
- stack.pop.send(method_name, *arguments) do | action, *rest_args |
43
+ stack.pop.__send__(method_name, *arguments) do | action, *rest_args |
46
44
  case action
47
45
  when :receiver
48
46
  receiver
@@ -62,7 +60,9 @@ module ContextR # :nodoc:
62
60
  method_name, arguments, block)
63
61
  proxies = []
64
62
  active_layers_as_classes.each do |layer|
65
- proxies += layer.context_proxies(contextified_class, method_name)
63
+ proxies += layer.context_proxies(receiver,
64
+ contextified_class,
65
+ method_name)
66
66
  end.compact
67
67
 
68
68
  proxies << core_proxy(receiver, contextified_class, method_name)
@@ -104,6 +104,10 @@ module ContextR # :nodoc:
104
104
  def meta_method?(method_name)
105
105
  method_name.to_s =~ /method_added(_with(out)?_contextr_listener)?/
106
106
  end
107
+
108
+ def self.extended(base)
109
+ base.instance_variable_set(:@layers, {})
110
+ end
107
111
  end
108
112
  self.extend(ClassMethods)
109
113
  end
@@ -1,41 +1,16 @@
1
- #--
2
- # The aliasing of these methods is done in a class_eval block to avoid code
3
- # documentation by RDoc.
4
- #++
5
- Module.class_eval do
6
- alias_method :include_without_layers, :include
7
- end
8
-
9
1
  class Module
10
- protected
11
- def include_with_layers(associations) # :nodoc:
12
- associations.each do | modul, layer |
13
- ContextR::layer_by_symbol(layer).add_method_collection(self, modul)
14
- end
15
- self
16
- end
17
-
18
- # call-seq:
19
- # include(module, ...) => self
20
- # include(module => layer_qualifier, ...) => self
21
- #
22
- # Invokes <code>Module.append_features</code> on each parameter in turn.
2
+ # Adds context-dependent behaviour to instances.
23
3
  #
24
- # If called with a hash, adds the module to the given layer. The behaviour
25
- # is associated with the class side of the object.
26
- #
27
- # module Mod
28
- # def name
29
- # "Hello from #{yield(:next)}.\n"
30
- # end
31
- # end
32
- #
33
4
  # class Klass
34
5
  # def name
35
6
  # "Klass"
36
7
  # end
37
8
  #
38
- # include Mod => :hello
9
+ # in_layer :hello do
10
+ # def name
11
+ # "Hello from #{super}.\n"
12
+ # end
13
+ # end
39
14
  # end
40
15
  #
41
16
  # k = Klass.new
@@ -45,13 +20,17 @@ class Module
45
20
  # end
46
21
  # k.name #=> "Klass.\n"
47
22
  #
48
- def include(*args)
49
- args.first.is_a?(Module) ? include_without_layers(*args) :
50
- include_with_layers(*args)
51
- end
52
- end
23
+ # Note: in_layer automatically generates the inner module
24
+ # and attaches it to the given layer. It is guaranteed, that the inner module
25
+ # used for method definitons will always be the same for any layer x class
26
+ # combination.
27
+ def in_layer(layer_symbol, &block)
28
+ extension = ContextR::stored_module_definitions[layer_symbol][self]
29
+
30
+ extension.module_eval(&block) if block_given?
53
31
 
54
- Module.class_eval do
55
- private :include
56
- private :include_with_layers
32
+ ContextR::layer_by_symbol(layer_symbol).add_method_collection(self,
33
+ extension)
34
+ extension
35
+ end
57
36
  end
@@ -1,71 +1,4 @@
1
- #--
2
- # The aliasing of these methods is done in a class_eval block to avoid code
3
- # documentation by RDoc.
4
- #++
5
- Object.class_eval do
6
- alias_method :extend_without_layers, :extend
7
- end
8
-
9
- class Object
10
- def extend_with_layers(associations) # :nodoc:
11
- klass = class << self; self; end
12
- associations.each do | modul, layer |
13
- ContextR::layer_by_symbol(layer).add_method_collection(klass, modul)
14
- end
15
- self
16
- end
17
-
18
- # call-seq:
19
- # obj.extend(module, ...) => obj
20
- # obj.extend(module => layer_qualifier, ...) => obj
21
- #
22
- # Adds to _obj_ the instance methods from each module given as a
23
- # parameter.
24
- #
25
- # module Mod
26
- # def hello
27
- # "Hello from Mod.\n"
28
- # end
29
- # end
30
- #
31
- # class Klass
32
- # def hello
33
- # "Hello from Klass.\n"
34
- # end
35
- # end
36
- #
37
- # k = Klass.new
38
- # k.hello #=> "Hello from Klass.\n"
39
- # k.extend(Mod) #=> #<Klass:0x401b3bc8>
40
- # k.hello #=> "Hello from Mod.\n"
41
- #
42
- # If called with a hash, adds the module to the given layer. The behaviour
43
- # is associated with the class side of the object.
44
- #
45
- # module Mod
46
- # def name
47
- # "Hello from #{yield(:next)}.\n"
48
- # end
49
- # end
50
- #
51
- # class Klass
52
- # def name
53
- # "Klass"
54
- # end
55
- # end
56
- #
57
- # k = Klass.new
58
- # k.extend(Mod => :hello) #=> #<Klass:0x401b3bc8>
59
- # k.name #=> "Klass.\n"
60
- # ContextR::with_layer :hello do
61
- # k.name #=> "Hello from Klass.\n"
62
- # end
63
- # k.name #=> "Klass.\n"
64
- def extend(*args)
65
- args.first.is_a?(Module) ? extend_without_layers(*args) :
66
- extend_with_layers(*args)
67
- end
68
-
1
+ class Object #:nodoc:
69
2
  def behavioural_class #:nodoc:
70
3
  if self.kind_of?(Module)
71
4
  class << self; self; end
@@ -4,7 +4,7 @@ module ContextR
4
4
  include UniqueId
5
5
 
6
6
  def listeners
7
- @listeners ||= { :method_added => {} }
7
+ @listeners ||= {:method_added => {}}
8
8
  end
9
9
 
10
10
  def register(listener, callback, options)
@@ -20,8 +20,8 @@ module ContextR
20
20
 
21
21
  def on_method_added(modul, name)
22
22
  version = self.new_unique_id
23
- self.listeners[:method_added][modul].each do | listener, method_name |
24
- listener.send( method_name, modul, name, version )
23
+ self.listeners[:method_added][modul].to_a.each do |listener, method|
24
+ listener.send(method, modul, name, version)
25
25
  end
26
26
  end
27
27
 
@@ -0,0 +1,47 @@
1
+ module ContextR
2
+ class InnerClass # :nodoc:
3
+ #--
4
+ # Copyright 2004, 2006 by Jim Weirich (jim@weirichhouse.org).
5
+ # All rights reserved.
6
+
7
+ # Permission is granted for use, copying, modification, distribution,
8
+ # and distribution of modified versions of this work as long as the
9
+ # above copyright notice is included.
10
+ #++
11
+ class << self
12
+ # Hide the method named +name+ in the BlankSlate class. Don't
13
+ # hide +instance_eval+ or any method beginning with "__".
14
+ def hide(name)
15
+ if instance_methods.include?(name.to_s) and
16
+ name !~ /^(__|instance_eval)/
17
+ @hidden_methods ||= {}
18
+ @hidden_methods[name.to_sym] = instance_method(name)
19
+ undef_method name
20
+ end
21
+ end
22
+
23
+ def find_hidden_method(name)
24
+ @hidden_methods ||= {}
25
+ @hidden_methods[name] || superclass.find_hidden_method(name)
26
+ end
27
+
28
+ # Redefine a previously hidden method so that it may be called on a blank
29
+ # slate object.
30
+ def reveal(name)
31
+ bound_method = nil
32
+ unbound_method = find_hidden_method(name)
33
+ fail "Don't know how to reveal method '#{name}'" unless unbound_method
34
+ define_method(name) do |*args|
35
+ bound_method ||= unbound_method.bind(self)
36
+ bound_method.call(*args)
37
+ end
38
+ end
39
+ end
40
+
41
+ instance_methods.each { |m| hide(m) }
42
+
43
+ def method_missing(method_name, *rest_args)
44
+ yield(:next, *rest_args)
45
+ end
46
+ end
47
+ end
@@ -1,88 +1,82 @@
1
1
  module ContextR # :nodoc:
2
2
  class Layer # :nodoc: all
3
- module ClassMethods
4
- def definitions
5
- @definitions ||= {}
6
- end
7
- def proxies
8
- @proxies ||= {}
9
- end
3
+ def definitions
4
+ @definitions ||= {}
5
+ end
6
+ def proxies
7
+ @proxies ||= {}
8
+ end
10
9
 
11
- def add_method_collection(contextified_class, methods_module)
12
- definitions[contextified_class] ||= []
13
- definitions[contextified_class].delete(methods_module)
14
- definitions[contextified_class].push(methods_module)
10
+ def add_method_collection(contextified_class, methods_module)
11
+ definitions[contextified_class] ||= []
12
+ definitions[contextified_class].delete(methods_module)
13
+ definitions[contextified_class].push(methods_module)
15
14
 
16
- (methods_module.instance_methods &
17
- contextified_class.instance_methods).each do | method_name |
18
- replace_core_method(contextified_class, method_name, 0)
19
- end
20
- register_callbacks(contextified_class, methods_module)
15
+ (methods_module.instance_methods &
16
+ contextified_class.instance_methods).each do | method_name |
17
+ replace_core_method(contextified_class, method_name, 0)
21
18
  end
19
+ register_callbacks(contextified_class, methods_module)
20
+ end
22
21
 
23
- def methods_modules_containing_method(contextified_class, method_name)
24
- if definitions.include?(contextified_class)
25
- definitions[contextified_class].select do | methods_module |
26
- methods_module.instance_methods.include?(method_name.to_s)
27
- end
28
- else
29
- []
22
+ def methods_modules_containing_method(contextified_class, method_name)
23
+ if definitions.include?(contextified_class)
24
+ definitions[contextified_class].select do | methods_module |
25
+ methods_module.instance_methods.include?(method_name.to_s)
30
26
  end
27
+ else
28
+ []
31
29
  end
30
+ end
32
31
 
33
- def context_proxies(contextified_class, method_name)
34
- methods_modules_containing_method(contextified_class, method_name).
35
- collect do | methods_module |
36
- context_proxy_for_module(methods_module)
37
- end.reverse
38
- end
39
-
40
- def context_proxy_for_module(methods_module)
41
- proxies[methods_module] ||= begin
42
- c = Class.new
43
- c.class_eval(%Q{
44
- include ObjectSpace._id2ref(#{methods_module.object_id})
45
- }, __FILE__, __LINE__)
46
- c.new
47
- end
48
- end
32
+ def context_proxies(receiver, contextified_class, method_name)
33
+ methods_modules_containing_method(contextified_class, method_name).
34
+ collect do | methods_module |
35
+ context_proxy_for_module(receiver, methods_module)
36
+ end.reverse
37
+ end
49
38
 
50
- def on_class_method_added(contextified_class, method_name, version)
51
- unless methods_modules_containing_method(contextified_class,
52
- method_name).empty?
53
- replace_core_method(contextified_class, method_name, version)
54
- end
39
+ def context_proxy_for_module(receiver, methods_module)
40
+ proxies[methods_module] ||= begin
41
+ c = Class.new(ContextR::InnerClass)
42
+ c.class_eval(%Q{
43
+ include ObjectSpace._id2ref(#{methods_module.object_id})
44
+ }, __FILE__, __LINE__)
45
+ c.new
55
46
  end
47
+ end
56
48
 
57
- def on_wrapper_method_added(methods_module, method_name, version)
58
- self.definitions.collect do | each_class, each_methods_modules |
59
- if each_methods_modules.include?(methods_module)
60
- each_class
61
- end
62
- end.compact.each do | contextified_class |
63
- replace_core_method(contextified_class, method_name, 0)
64
- end
49
+ def on_class_method_added(contextified_class, method_name, version)
50
+ unless methods_modules_containing_method(contextified_class,
51
+ method_name).empty?
52
+ replace_core_method(contextified_class, method_name, version)
65
53
  end
54
+ end
66
55
 
67
- def replace_core_method(contextified_class, method_name, version)
68
- ContextR::observe_core_method(contextified_class, method_name.to_sym,
69
- version)
56
+ def on_wrapper_method_added(methods_module, method_name, version)
57
+ self.definitions.collect do | each_class, each_methods_modules |
58
+ if each_methods_modules.include?(methods_module)
59
+ each_class
60
+ end
61
+ end.compact.select do |contextified_class|
62
+ contextified_class.instance_methods.include?(method_name.to_s)
63
+ end.each do | contextified_class |
64
+ replace_core_method(contextified_class, method_name, 0)
70
65
  end
66
+ end
71
67
 
72
- def register_callbacks(cclass, mmodule)
73
- { :on_wrapper_method_added => mmodule,
74
- :on_class_method_added => cclass }.each do | callback, klass |
75
- ContextR::EventMachine.register(self, callback,
76
- :on_event => :method_added,
77
- :in_class => klass)
78
- end
79
- end
68
+ def replace_core_method(contextified_class, method_name, version)
69
+ ContextR::observe_core_method(contextified_class, method_name.to_sym,
70
+ version)
80
71
  end
81
-
82
- self.extend(ClassMethods)
83
-
84
- def self.inherited(klass)
85
- klass.extend(ClassMethods)
72
+
73
+ def register_callbacks(cclass, mmodule)
74
+ {:on_wrapper_method_added => mmodule,
75
+ :on_class_method_added => cclass }.each do | callback, klass |
76
+ ContextR::EventMachine.register(self, callback,
77
+ :on_event => :method_added,
78
+ :in_class => klass)
79
+ end
86
80
  end
87
81
  end
88
82
  end