glue 0.13.0 → 0.14.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,5 +1,24 @@
1
+ 24-03-2005 George Moschovitis <gm@navel.gr>
2
+
3
+ * test/glue/tc_property.rb: added more tests.
4
+
5
+ * lib/glue/property.rb (#enchant): moved inheritance code
6
+ here,
7
+ Totaly recoded __props/__meta inhertiance implementation,
8
+ it works now!
9
+
10
+ 20-03-2005 George Moschovitis <gm@navel.gr>
11
+
12
+ * moved vendor directory here (to be removed soon).
13
+
14
+ 19-03-2005 George Moschovitis <gm@navel.gr>
15
+
16
+ * lib/glue/logger.rb (Logging): added.
17
+
1
18
  17-03-2005 George Moschovitis <gm@navel.gr>
2
19
 
20
+ * --- VERSION 0.13.0 ---
21
+
3
22
  * Rakefile: updated and fixed bugs.
4
23
 
5
24
  * test/*: changes to make the tests pass again.
data/README CHANGED
@@ -1,3 +1,3 @@
1
- = Glue
1
+ = Glue 0.14.0
2
2
 
3
3
  Useful utilites and methods.
data/Rakefile CHANGED
@@ -12,7 +12,7 @@ task :default => :package
12
12
 
13
13
  Rake::TestTask.new(:test_all) do |t|
14
14
  t.libs << 'test'
15
- t.test_files = FileList['test/**/tc*.rb']
15
+ t.test_files = FileList['test/**/*.rb']
16
16
  t.verbose = true
17
17
  end
18
18
 
data/doc/RELEASES CHANGED
@@ -1,3 +1,7 @@
1
+ == Version 0.14.0 was released on 28/03/2005.
2
+
3
+ Fixes nasty property inheritance bug.
4
+
1
5
  == Version 0.13.0 was released on 17/03/2005.
2
6
 
3
7
  The first release as a standalone gem.
data/lib/glue.rb CHANGED
@@ -4,7 +4,7 @@
4
4
  #
5
5
  # George Moschovitis <gm@navel.gr>
6
6
  # (c) 2004-2005 Navel, all rights reserved.
7
- # $Id: glue.rb 300 2005-03-16 13:23:10Z gmosx $
7
+ # $Id: glue.rb 326 2005-03-28 11:07:17Z gmosx $
8
8
 
9
9
  require 'English'
10
10
  require 'pp'
@@ -57,6 +57,10 @@ module Glue
57
57
 
58
58
  # The version.
59
59
 
60
- Version = '0.13.0'
60
+ Version = '0.14.0'
61
+
62
+ # Library path.
63
+
64
+ LibPath = File.dirname(__FILE__)
61
65
 
62
66
  end
@@ -11,7 +11,10 @@
11
11
  # Example:
12
12
  #
13
13
  # mattr_accessor :my_attr, 'Default value'
14
+ #
15
+ # FIXME: I think those methods do *not* work as expected.
14
16
  #++
17
+
15
18
  class Module # :nodoc:
16
19
 
17
20
  def mattr_reader(*params)
@@ -1,5 +1,5 @@
1
1
  # Code from RubyOnRails (http://www.rubyonrails.com)
2
- # Copyright (c) 2004 David Heinemeier Hansson.
2
+ # Copyright (c) 2004-2005 David Heinemeier Hansson.
3
3
 
4
4
  module N
5
5
 
data/lib/glue/logger.rb CHANGED
@@ -1,11 +1,15 @@
1
1
  # * George Moschovitis <gm@navel.gr>
2
2
  # (c) 2004-2005 Navel, all rights reserved.
3
- # $Id: logger.rb 282 2005-03-10 12:24:53Z gmosx $
3
+ # $Id: logger.rb 316 2005-03-21 10:14:03Z gmosx $
4
4
 
5
5
  require 'logger'
6
6
 
7
7
  # A simple wrapper arround the Ruby logger. Mainly for
8
8
  # compatibility purposes.
9
+ #
10
+ #--
11
+ # TODO: implement as mixin that can be added to Log4R.
12
+ #++
9
13
 
10
14
  class Logger
11
15
  alias_method :devel, :debug
@@ -63,16 +67,20 @@ class Logger
63
67
  end
64
68
  end
65
69
  end
70
+
66
71
  TRACE_STYLES = {} # :nodoc:
67
- TRACE_STYLES.update( :pp => :pp_s, :s => :to_s, :p => :inspect, :y => :to_yaml,
68
- :yaml => :to_yaml, :inspect => :inspect, :to_yaml => :to_yaml )
72
+ TRACE_STYLES.update(
73
+ :pp => :pp_s, :s => :to_s, :p => :inspect,
74
+ :y => :to_yaml, :yaml => :to_yaml,
75
+ :inspect => :inspect, :to_yaml => :to_yaml
76
+ )
69
77
 
70
78
  # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
71
79
  # Global logger interface.
72
80
  # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
73
81
 
74
82
  # Override the logger with your custom version.
75
- #
83
+
76
84
  @@global_logger = Logger.new(STDERR)
77
85
 
78
86
  def self.set(logger)
@@ -145,3 +153,20 @@ class Logger
145
153
 
146
154
  end
147
155
 
156
+ module N
157
+
158
+ # Add logging capabilities to the including class.
159
+ # When using the log/logger variables always check
160
+ # for nil:
161
+ #
162
+ # log.info "your #{expensive_calculation} comes here" if @log
163
+ #
164
+ # This way the expensive calculation is avoided if the
165
+ # logger is dissabled (@log == nil).
166
+
167
+ module Logging
168
+ attr_accessor :logger
169
+ alias_method :log, :logger
170
+ end
171
+
172
+ end
data/lib/glue/property.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # * George Moschovitis <gm@navel.gr>
2
2
  # * Michael Neumann <mneumann@ntecs.de>
3
3
  # (c) 2004-2005 Navel, all rights reserved.
4
- # $Id: property.rb 282 2005-03-10 12:24:53Z gmosx $
4
+ # $Id: property.rb 326 2005-03-28 11:07:17Z gmosx $
5
5
 
6
6
  require 'glue/attribute'
7
7
  require 'glue/array'
@@ -90,27 +90,65 @@ module PropertyUtils
90
90
  #++
91
91
 
92
92
  def self.enchant(target, force = false)
93
- unless target.singleton_methods.include?('__props')
93
+ unless target.instance_variables.include?('@__props')
94
+ target.instance_variable_set('@__meta', N::SafeHash.new)
95
+ target.instance_variable_set('@__props', N::SafeArray.new)
96
+
97
+ # gmosx: Ruby surprises and amazes me! We are in the Metaclass
98
+ # when defining methods and attributes so @__props is really
99
+ # a class scoped variable that unlike @@__props is not shared
100
+ # through the hierarchy.
101
+
94
102
  target.module_eval %{
95
- @@__meta = N::SafeHash.new
96
- @@__props = N::SafeArray.new
97
-
98
103
  def self.__props
99
- @@__props
104
+ @__props
100
105
  end
101
106
 
102
107
  def self.__props=(props)
103
- @@__props = props
108
+ @__props = props
104
109
  end
105
110
 
106
111
  def self.__meta
107
- @@__meta
112
+ @__meta
108
113
  end
109
114
 
110
115
  def self.__meta=(meta)
111
- @@__meta = meta
116
+ @__meta = meta
112
117
  end
113
118
  }
119
+
120
+ if target.is_a?(Class)
121
+
122
+ # Add some extra code to append features to
123
+ # subclasses.
124
+
125
+ target.module_eval %{
126
+ def self.inherited(child)
127
+ N::PropertyUtils.enchant(child)
128
+ N::PropertyUtils.copy_props(self, child)
129
+ # gmosx: We have to define @@__props first to avoid reusing
130
+ # the hash from the module. super must stay at the end.
131
+ super
132
+ end
133
+ }
134
+
135
+ else
136
+
137
+ # Add some extra code for modules to append
138
+ # their features to classes that include it.
139
+
140
+ target.module_eval %{
141
+ def self.append_features(base)
142
+ N::PropertyUtils.enchant(base)
143
+ N::PropertyUtils.copy_props(self, base)
144
+ # gmosx: We have to define @@__props first to avoid reusing
145
+ # the hash from the module. super must stay at the end.
146
+ N::PropertyUtils.include_meta_mixins(base)
147
+ super
148
+ end
149
+ }
150
+
151
+ end
114
152
  end
115
153
  end
116
154
 
@@ -281,40 +319,6 @@ class Module
281
319
 
282
320
  N::PropertyUtils.enchant(self)
283
321
 
284
- if self.is_a?(Class)
285
-
286
- # Add some extra code to append features to
287
- # subclasses.
288
-
289
- self.module_eval %{
290
- def self.inherited(sub)
291
- N::PropertyUtils.enchant(sub)
292
- N::PropertyUtils.copy_props(self, sub)
293
- # gmosx: We have to define @@__props first to avoid reusing
294
- # the hash from the module. super must stay at the end.
295
- super
296
- end
297
- }
298
- else
299
-
300
- # Add some extra code for modules to append
301
- # their features to classes that include it.
302
-
303
- self.module_eval %{
304
- def self.append_features(base)
305
- N::PropertyUtils.enchant(base)
306
- N::PropertyUtils.copy_props(self, base)
307
-
308
- # gmosx: We have to define @@__props first to avoid reusing
309
- # the hash from the module. super must stay at the end.
310
-
311
- N::PropertyUtils.include_meta_mixins(base)
312
-
313
- super
314
- end
315
- }
316
- end
317
-
318
322
  property = N::Property.new(symbol, klass, meta)
319
323
 
320
324
  reader = meta[:reader] || true
@@ -399,9 +403,9 @@ class Module
399
403
  N::PropertyUtils.enchant(self)
400
404
 
401
405
  self.module_eval %{
402
- @@__meta[key] ||= []
403
- @@__meta[key].delete_if { |v| val == v }
404
- @@__meta[key] << val
406
+ @__meta[key] ||= []
407
+ @__meta[key].delete_if { |v| val == v }
408
+ @__meta[key] << val
405
409
  }
406
410
  end
407
411
 
@@ -47,6 +47,9 @@ class SubMsg < Msg
47
47
 
48
48
  # duplicate definition with different type!
49
49
  prop_accessor :count, Float
50
+
51
+ # another property
52
+ prop_accessor :another, Fixnum
50
53
  end
51
54
 
52
55
  class TC_N_Properties < Test::Unit::TestCase
@@ -62,9 +65,13 @@ class TC_N_Properties < Test::Unit::TestCase
62
65
  def test_props
63
66
 
64
67
  # bug: props for subclasses.
68
+ # bug: props propagated to base classes.
65
69
 
66
70
  assert(SubMsg.__props)
67
- assert_equal(Msg.__props.size(), SubMsg.__props.size())
71
+ assert_equal(Msg.__props.size(), SubMsg.__props.size() - 1)
72
+
73
+ assert_equal(11, Msg.__props.size)
74
+ assert_equal(12, SubMsg.__props.size)
68
75
 
69
76
  # bug: duplicate definition
70
77
 
data/vendor/README ADDED
@@ -0,0 +1,11 @@
1
+ = Extensions and Libraries from other vendors.
2
+
3
+ Libraries from other vendors belong here. This file
4
+
5
+ === Included libraries
6
+
7
+ * extensions
8
+ * breakpointer
9
+ * dev-utils
10
+ * postgres-pr
11
+
@@ -0,0 +1,81 @@
1
+ begin
2
+ require 'simplecc'
3
+ rescue LoadError
4
+ def Continuation.create(*args, &block)
5
+ cc = nil; result = callcc {|c| cc = c; block.call(cc) if block and args.empty?}
6
+ result ||= args
7
+ return *[cc, *result]
8
+ end
9
+ end
10
+
11
+ # This method returns the binding of the method that called your
12
+ # method. It will raise an Exception when you're not inside a method.
13
+ #
14
+ # It's used like this:
15
+ # def inc_counter(amount = 1)
16
+ # Binding.of_caller do |binding|
17
+ # # Create a lambda that will increase the variable 'counter'
18
+ # # in the caller of this method when called.
19
+ # inc = eval("lambda { |arg| counter += arg }", binding)
20
+ # # We can refer to amount from inside this block safely.
21
+ # inc.call(amount)
22
+ # end
23
+ # # No other statements can go here. Put them inside the block.
24
+ # end
25
+ # counter = 0
26
+ # 2.times { inc_counter }
27
+ # counter # => 2
28
+ #
29
+ # Binding.of_caller must be the last statement in the method.
30
+ # This means that you will have to put everything you want to
31
+ # do after the call to Binding.of_caller into the block of it.
32
+ # This should be no problem however, because Ruby has closures.
33
+ # If you don't do this an Exception will be raised. Because of
34
+ # the way that Binding.of_caller is implemented it has to be
35
+ # done this way.
36
+ def Binding.of_caller(&block)
37
+ old_critical = Thread.critical
38
+ Thread.critical = true
39
+ count = 0
40
+ cc, result, error, extra_data = Continuation.create(nil, nil)
41
+ error.call if error
42
+
43
+ tracer = lambda do |*args|
44
+ type, context, extra_data = args[0], args[4], args
45
+ if type == "return"
46
+ count += 1
47
+ # First this method and then calling one will return --
48
+ # the trace event of the second event gets the context
49
+ # of the method which called the method that called this
50
+ # method.
51
+ if count == 2
52
+ # It would be nice if we could restore the trace_func
53
+ # that was set before we swapped in our own one, but
54
+ # this is impossible without overloading set_trace_func
55
+ # in current Ruby.
56
+ set_trace_func(nil)
57
+ cc.call(eval("binding", context), nil, extra_data)
58
+ end
59
+ elsif type == "line" then
60
+ nil
61
+ elsif type == "c-return" and extra_data[3] == :set_trace_func then
62
+ nil
63
+ else
64
+ set_trace_func(nil)
65
+ error_msg = "Binding.of_caller used in non-method context or " +
66
+ "trailing statements of method using it aren't in the block."
67
+ cc.call(nil, lambda { raise(ArgumentError, error_msg) }, nil)
68
+ end
69
+ end
70
+
71
+ unless result
72
+ set_trace_func(tracer)
73
+ return nil
74
+ else
75
+ Thread.critical = old_critical
76
+ case block.arity
77
+ when 1 then yield(result)
78
+ else yield(result, extra_data)
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,53 @@
1
+ #!/usr/bin/env ruby
2
+ #--
3
+ # Copyright 2004 by Jim Weirich (jim@weirichhouse.org).
4
+ # All rights reserved.
5
+
6
+ # Permission is granted for use, copying, modification, distribution,
7
+ # and distribution of modified versions of this work as long as the
8
+ # above copyright notice is included.
9
+ #++
10
+
11
+ module Builder #:nodoc:
12
+
13
+ # BlankSlate provides an abstract base class with no predefined
14
+ # methods (except for <tt>\_\_send__</tt> and <tt>\_\_id__</tt>).
15
+ # BlankSlate is useful as a base class when writing classes that
16
+ # depend upon <tt>method_missing</tt> (e.g. dynamic proxies).
17
+ class BlankSlate #:nodoc:
18
+ class << self
19
+ def hide(name)
20
+ undef_method name if
21
+ instance_methods.include?(name.to_s) and
22
+ name !~ /^(__|instance_eval)/
23
+ end
24
+ end
25
+
26
+ instance_methods.each { |m| hide(m) }
27
+ end
28
+ end
29
+
30
+ # Since Ruby is very dynamic, methods added to the ancestors of
31
+ # BlankSlate <em>after BlankSlate is defined</em> will show up in the
32
+ # list of available BlankSlate methods. We handle this by defining a hook in the Object and Kernel classes that will hide any defined
33
+ module Kernel #:nodoc:
34
+ class << self
35
+ alias_method :blank_slate_method_added, :method_added
36
+ def method_added(name)
37
+ blank_slate_method_added(name)
38
+ return if self != Kernel
39
+ Builder::BlankSlate.hide(name)
40
+ end
41
+ end
42
+ end
43
+
44
+ class Object #:nodoc:
45
+ class << self
46
+ alias_method :blank_slate_method_added, :method_added
47
+ def method_added(name)
48
+ blank_slate_method_added(name)
49
+ return if self != Object
50
+ Builder::BlankSlate.hide(name)
51
+ end
52
+ end
53
+ end