contextr 0.1.1 → 0.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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