glue 0.13.0 → 0.14.0

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/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