activesupport 1.4.4 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activesupport might be problematic. Click here for more details.

Files changed (126) hide show
  1. data/CHANGELOG +263 -7
  2. data/lib/active_support.rb +9 -4
  3. data/lib/active_support/basic_object.rb +5 -0
  4. data/lib/active_support/buffered_logger.rb +107 -0
  5. data/lib/active_support/clean_logger.rb +94 -5
  6. data/lib/active_support/core_ext.rb +4 -1
  7. data/lib/active_support/core_ext/array.rb +8 -2
  8. data/lib/active_support/core_ext/array/access.rb +28 -0
  9. data/lib/active_support/core_ext/array/conversions.rb +28 -15
  10. data/lib/active_support/core_ext/array/extract_options.rb +19 -0
  11. data/lib/active_support/core_ext/array/grouping.rb +20 -7
  12. data/lib/active_support/core_ext/array/random_access.rb +12 -0
  13. data/lib/active_support/core_ext/bigdecimal.rb +1 -2
  14. data/lib/active_support/core_ext/bigdecimal/{formatting.rb → conversions.rb} +1 -2
  15. data/lib/active_support/core_ext/blank.rb +2 -8
  16. data/lib/active_support/core_ext/cgi.rb +2 -2
  17. data/lib/active_support/core_ext/class.rb +4 -3
  18. data/lib/active_support/core_ext/class/attribute_accessors.rb +1 -1
  19. data/lib/active_support/core_ext/class/delegating_attributes.rb +40 -0
  20. data/lib/active_support/core_ext/class/inheritable_attributes.rb +3 -3
  21. data/lib/active_support/core_ext/class/removal.rb +2 -2
  22. data/lib/active_support/core_ext/date.rb +5 -1
  23. data/lib/active_support/core_ext/date/behavior.rb +13 -0
  24. data/lib/active_support/core_ext/date/calculations.rb +188 -0
  25. data/lib/active_support/core_ext/date/conversions.rb +69 -13
  26. data/lib/active_support/core_ext/date_time.rb +10 -0
  27. data/lib/active_support/core_ext/date_time/calculations.rb +77 -0
  28. data/lib/active_support/core_ext/date_time/conversions.rb +54 -0
  29. data/lib/active_support/core_ext/duplicable.rb +37 -0
  30. data/lib/active_support/core_ext/enumerable.rb +1 -0
  31. data/lib/active_support/core_ext/exception.rb +2 -2
  32. data/lib/active_support/core_ext/file.rb +21 -0
  33. data/lib/active_support/core_ext/float.rb +5 -0
  34. data/lib/active_support/core_ext/float/rounding.rb +24 -0
  35. data/lib/active_support/core_ext/hash.rb +5 -5
  36. data/lib/active_support/core_ext/hash/conversions.rb +86 -34
  37. data/lib/active_support/core_ext/hash/diff.rb +8 -0
  38. data/lib/active_support/core_ext/hash/except.rb +24 -0
  39. data/lib/active_support/core_ext/hash/indifferent_access.rb +15 -2
  40. data/lib/active_support/core_ext/hash/keys.rb +10 -3
  41. data/lib/active_support/core_ext/hash/reverse_merge.rb +2 -2
  42. data/lib/active_support/core_ext/hash/slice.rb +28 -0
  43. data/lib/active_support/core_ext/integer.rb +2 -2
  44. data/lib/active_support/core_ext/kernel.rb +5 -4
  45. data/lib/active_support/core_ext/kernel/debugger.rb +13 -0
  46. data/lib/active_support/core_ext/module.rb +8 -7
  47. data/lib/active_support/core_ext/module/aliasing.rb +17 -5
  48. data/lib/active_support/core_ext/module/attr_accessor_with_default.rb +31 -0
  49. data/lib/active_support/core_ext/module/attribute_accessors.rb +1 -1
  50. data/lib/active_support/core_ext/module/delegation.rb +21 -0
  51. data/lib/active_support/core_ext/name_error.rb +2 -2
  52. data/lib/active_support/core_ext/numeric.rb +2 -2
  53. data/lib/active_support/core_ext/numeric/time.rb +30 -11
  54. data/lib/active_support/core_ext/object.rb +3 -2
  55. data/lib/active_support/core_ext/object/extending.rb +40 -29
  56. data/lib/active_support/core_ext/object/instance_variables.rb +22 -0
  57. data/lib/active_support/core_ext/object/misc.rb +29 -4
  58. data/lib/active_support/core_ext/pathname.rb +1 -1
  59. data/lib/active_support/core_ext/range.rb +7 -1
  60. data/lib/active_support/core_ext/range/blockless_step.rb +22 -0
  61. data/lib/active_support/core_ext/range/conversions.rb +8 -6
  62. data/lib/active_support/core_ext/range/include_range.rb +22 -0
  63. data/lib/active_support/core_ext/range/overlaps.rb +12 -0
  64. data/lib/active_support/core_ext/string.rb +10 -7
  65. data/lib/active_support/core_ext/string/conversions.rb +5 -1
  66. data/lib/active_support/core_ext/string/unicode.rb +2 -2
  67. data/lib/active_support/core_ext/string/xchar.rb +11 -0
  68. data/lib/active_support/core_ext/symbol.rb +12 -10
  69. data/lib/active_support/core_ext/test.rb +1 -0
  70. data/lib/active_support/core_ext/test/unit/assertions.rb +62 -0
  71. data/lib/active_support/core_ext/time.rb +4 -2
  72. data/lib/active_support/core_ext/time/behavior.rb +13 -0
  73. data/lib/active_support/core_ext/time/calculations.rb +87 -54
  74. data/lib/active_support/core_ext/time/conversions.rb +71 -10
  75. data/lib/active_support/dependencies.rb +25 -24
  76. data/lib/active_support/deprecation.rb +4 -2
  77. data/lib/active_support/duration.rb +86 -0
  78. data/lib/active_support/inflections.rb +2 -1
  79. data/lib/active_support/inflector.rb +13 -6
  80. data/lib/active_support/json.rb +22 -39
  81. data/lib/active_support/json/decoding.rb +60 -0
  82. data/lib/active_support/json/encoders/date.rb +5 -0
  83. data/lib/active_support/json/encoders/date_time.rb +5 -0
  84. data/lib/active_support/json/encoders/enumerable.rb +12 -0
  85. data/lib/active_support/json/encoders/false_class.rb +5 -0
  86. data/lib/active_support/json/encoders/hash.rb +50 -0
  87. data/lib/active_support/json/encoders/nil_class.rb +5 -0
  88. data/lib/active_support/json/encoders/numeric.rb +5 -0
  89. data/lib/active_support/json/encoders/object.rb +6 -0
  90. data/lib/active_support/json/encoders/regexp.rb +5 -0
  91. data/lib/active_support/json/encoders/string.rb +30 -0
  92. data/lib/active_support/json/encoders/symbol.rb +5 -0
  93. data/lib/active_support/json/encoders/time.rb +5 -0
  94. data/lib/active_support/json/encoders/true_class.rb +5 -0
  95. data/lib/active_support/json/encoding.rb +38 -0
  96. data/lib/active_support/json/variable.rb +10 -0
  97. data/lib/active_support/multibyte.rb +7 -5
  98. data/lib/active_support/multibyte/chars.rb +6 -0
  99. data/lib/active_support/multibyte/handlers/utf8_handler.rb +115 -5
  100. data/lib/active_support/option_merger.rb +7 -7
  101. data/lib/active_support/ordered_options.rb +22 -17
  102. data/lib/active_support/test_case.rb +5 -0
  103. data/lib/active_support/testing.rb +1 -0
  104. data/lib/active_support/testing/default.rb +12 -0
  105. data/lib/active_support/values/time_zone.rb +3 -3
  106. data/lib/active_support/vendor.rb +14 -0
  107. data/lib/active_support/vendor/builder-2.1.2/blankslate.rb +113 -0
  108. data/lib/active_support/vendor/{builder.rb → builder-2.1.2/builder.rb} +0 -0
  109. data/lib/active_support/vendor/builder-2.1.2/builder/blankslate.rb +20 -0
  110. data/lib/active_support/vendor/builder-2.1.2/builder/css.rb +250 -0
  111. data/lib/active_support/vendor/{builder → builder-2.1.2/builder}/xchar.rb +11 -8
  112. data/lib/active_support/vendor/{builder → builder-2.1.2/builder}/xmlbase.rb +38 -44
  113. data/lib/active_support/vendor/{builder → builder-2.1.2/builder}/xmlevents.rb +1 -1
  114. data/lib/active_support/vendor/{builder → builder-2.1.2/builder}/xmlmarkup.rb +40 -39
  115. data/lib/active_support/vendor/{xml_simple.rb → xml-simple-1.0.11/xmlsimple.rb} +3 -3
  116. data/lib/active_support/version.rb +3 -3
  117. data/lib/active_support/whiny_nil.rb +12 -12
  118. data/lib/activesupport.rb +1 -0
  119. metadata +69 -17
  120. data/lib/active_support/binding_of_caller.rb +0 -84
  121. data/lib/active_support/breakpoint.rb +0 -528
  122. data/lib/active_support/caching_tools.rb +0 -62
  123. data/lib/active_support/json/encoders.rb +0 -25
  124. data/lib/active_support/json/encoders/core.rb +0 -70
  125. data/lib/active_support/reloadable.rb +0 -60
  126. data/lib/active_support/vendor/builder/blankslate.rb +0 -63
@@ -1,23 +1,23 @@
1
- # Extensions to nil which allow for more helpful error messages for
1
+ # Extensions to nil which allow for more helpful error messages for
2
2
  # people who are new to rails.
3
3
  #
4
4
  # The aim is to ensure that when users pass nil to methods where that isn't
5
5
  # appropriate, instead of NoMethodError and the name of some method used
6
- # by the framework users will see a message explaining what type of object
6
+ # by the framework users will see a message explaining what type of object
7
7
  # was expected.
8
8
 
9
9
  class NilClass
10
- WHINERS = [ ::ActiveRecord::Base, ::Array ]
11
-
10
+ WHINERS = [::Array]
11
+ WHINERS << ::ActiveRecord::Base if defined? ::ActiveRecord
12
+
12
13
  @@method_class_map = Hash.new
13
-
14
+
14
15
  WHINERS.each do |klass|
15
16
  methods = klass.public_instance_methods - public_instance_methods
16
- methods.each do |method|
17
- @@method_class_map[method.to_sym] = klass
18
- end
17
+ class_name = klass.name
18
+ methods.each { |method| @@method_class_map[method.to_sym] = class_name }
19
19
  end
20
-
20
+
21
21
  def id
22
22
  raise RuntimeError, "Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id", caller
23
23
  end
@@ -27,11 +27,11 @@ class NilClass
27
27
  raise_nil_warning_for @@method_class_map[method], method, caller
28
28
  end
29
29
 
30
- def raise_nil_warning_for(klass = nil, selector = nil, with_caller = nil)
30
+ def raise_nil_warning_for(class_name = nil, selector = nil, with_caller = nil)
31
31
  message = "You have a nil object when you didn't expect it!"
32
- message << "\nYou might have expected an instance of #{klass}." if klass
32
+ message << "\nYou might have expected an instance of #{class_name}." if class_name
33
33
  message << "\nThe error occurred while evaluating nil.#{selector}" if selector
34
-
34
+
35
35
  raise NoMethodError, message, with_caller || caller
36
36
  end
37
37
  end
@@ -0,0 +1 @@
1
+ require 'active_support'
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.4
3
3
  specification_version: 1
4
4
  name: activesupport
5
5
  version: !ruby/object:Gem::Version
6
- version: 1.4.4
7
- date: 2007-10-12 00:00:00 -05:00
6
+ version: 2.0.0
7
+ date: 2007-12-06 00:00:00 -06:00
8
8
  summary: Support and utility classes used by the Rails framework.
9
9
  require_paths:
10
10
  - lib
@@ -32,17 +32,19 @@ files:
32
32
  - CHANGELOG
33
33
  - README
34
34
  - lib/active_support
35
- - lib/active_support/binding_of_caller.rb
36
- - lib/active_support/breakpoint.rb
37
- - lib/active_support/caching_tools.rb
35
+ - lib/active_support/basic_object.rb
36
+ - lib/active_support/buffered_logger.rb
38
37
  - lib/active_support/clean_logger.rb
39
38
  - lib/active_support/core_ext
40
39
  - lib/active_support/core_ext/array
40
+ - lib/active_support/core_ext/array/access.rb
41
41
  - lib/active_support/core_ext/array/conversions.rb
42
+ - lib/active_support/core_ext/array/extract_options.rb
42
43
  - lib/active_support/core_ext/array/grouping.rb
44
+ - lib/active_support/core_ext/array/random_access.rb
43
45
  - lib/active_support/core_ext/array.rb
44
46
  - lib/active_support/core_ext/bigdecimal
45
- - lib/active_support/core_ext/bigdecimal/formatting.rb
47
+ - lib/active_support/core_ext/bigdecimal/conversions.rb
46
48
  - lib/active_support/core_ext/bigdecimal.rb
47
49
  - lib/active_support/core_ext/blank.rb
48
50
  - lib/active_support/core_ext/cgi
@@ -50,20 +52,34 @@ files:
50
52
  - lib/active_support/core_ext/cgi.rb
51
53
  - lib/active_support/core_ext/class
52
54
  - lib/active_support/core_ext/class/attribute_accessors.rb
55
+ - lib/active_support/core_ext/class/delegating_attributes.rb
53
56
  - lib/active_support/core_ext/class/inheritable_attributes.rb
54
57
  - lib/active_support/core_ext/class/removal.rb
55
58
  - lib/active_support/core_ext/class.rb
56
59
  - lib/active_support/core_ext/date
60
+ - lib/active_support/core_ext/date/behavior.rb
61
+ - lib/active_support/core_ext/date/calculations.rb
57
62
  - lib/active_support/core_ext/date/conversions.rb
58
63
  - lib/active_support/core_ext/date.rb
64
+ - lib/active_support/core_ext/date_time
65
+ - lib/active_support/core_ext/date_time/calculations.rb
66
+ - lib/active_support/core_ext/date_time/conversions.rb
67
+ - lib/active_support/core_ext/date_time.rb
68
+ - lib/active_support/core_ext/duplicable.rb
59
69
  - lib/active_support/core_ext/enumerable.rb
60
70
  - lib/active_support/core_ext/exception.rb
71
+ - lib/active_support/core_ext/file.rb
72
+ - lib/active_support/core_ext/float
73
+ - lib/active_support/core_ext/float/rounding.rb
74
+ - lib/active_support/core_ext/float.rb
61
75
  - lib/active_support/core_ext/hash
62
76
  - lib/active_support/core_ext/hash/conversions.rb
63
77
  - lib/active_support/core_ext/hash/diff.rb
78
+ - lib/active_support/core_ext/hash/except.rb
64
79
  - lib/active_support/core_ext/hash/indifferent_access.rb
65
80
  - lib/active_support/core_ext/hash/keys.rb
66
81
  - lib/active_support/core_ext/hash/reverse_merge.rb
82
+ - lib/active_support/core_ext/hash/slice.rb
67
83
  - lib/active_support/core_ext/hash.rb
68
84
  - lib/active_support/core_ext/integer
69
85
  - lib/active_support/core_ext/integer/even_odd.rb
@@ -72,6 +88,7 @@ files:
72
88
  - lib/active_support/core_ext/kernel
73
89
  - lib/active_support/core_ext/kernel/agnostics.rb
74
90
  - lib/active_support/core_ext/kernel/daemonizing.rb
91
+ - lib/active_support/core_ext/kernel/debugger.rb
75
92
  - lib/active_support/core_ext/kernel/reporting.rb
76
93
  - lib/active_support/core_ext/kernel/requires.rb
77
94
  - lib/active_support/core_ext/kernel.rb
@@ -79,6 +96,7 @@ files:
79
96
  - lib/active_support/core_ext/logger.rb
80
97
  - lib/active_support/core_ext/module
81
98
  - lib/active_support/core_ext/module/aliasing.rb
99
+ - lib/active_support/core_ext/module/attr_accessor_with_default.rb
82
100
  - lib/active_support/core_ext/module/attr_internal.rb
83
101
  - lib/active_support/core_ext/module/attribute_accessors.rb
84
102
  - lib/active_support/core_ext/module/delegation.rb
@@ -93,6 +111,7 @@ files:
93
111
  - lib/active_support/core_ext/numeric.rb
94
112
  - lib/active_support/core_ext/object
95
113
  - lib/active_support/core_ext/object/extending.rb
114
+ - lib/active_support/core_ext/object/instance_variables.rb
96
115
  - lib/active_support/core_ext/object/misc.rb
97
116
  - lib/active_support/core_ext/object.rb
98
117
  - lib/active_support/core_ext/pathname
@@ -100,7 +119,10 @@ files:
100
119
  - lib/active_support/core_ext/pathname.rb
101
120
  - lib/active_support/core_ext/proc.rb
102
121
  - lib/active_support/core_ext/range
122
+ - lib/active_support/core_ext/range/blockless_step.rb
103
123
  - lib/active_support/core_ext/range/conversions.rb
124
+ - lib/active_support/core_ext/range/include_range.rb
125
+ - lib/active_support/core_ext/range/overlaps.rb
104
126
  - lib/active_support/core_ext/range.rb
105
127
  - lib/active_support/core_ext/string
106
128
  - lib/active_support/core_ext/string/access.rb
@@ -109,21 +131,42 @@ files:
109
131
  - lib/active_support/core_ext/string/iterators.rb
110
132
  - lib/active_support/core_ext/string/starts_ends_with.rb
111
133
  - lib/active_support/core_ext/string/unicode.rb
134
+ - lib/active_support/core_ext/string/xchar.rb
112
135
  - lib/active_support/core_ext/string.rb
113
136
  - lib/active_support/core_ext/symbol.rb
137
+ - lib/active_support/core_ext/test
138
+ - lib/active_support/core_ext/test/unit
139
+ - lib/active_support/core_ext/test/unit/assertions.rb
140
+ - lib/active_support/core_ext/test.rb
114
141
  - lib/active_support/core_ext/time
142
+ - lib/active_support/core_ext/time/behavior.rb
115
143
  - lib/active_support/core_ext/time/calculations.rb
116
144
  - lib/active_support/core_ext/time/conversions.rb
117
145
  - lib/active_support/core_ext/time.rb
118
146
  - lib/active_support/core_ext.rb
119
147
  - lib/active_support/dependencies.rb
120
148
  - lib/active_support/deprecation.rb
149
+ - lib/active_support/duration.rb
121
150
  - lib/active_support/inflections.rb
122
151
  - lib/active_support/inflector.rb
123
152
  - lib/active_support/json
153
+ - lib/active_support/json/decoding.rb
124
154
  - lib/active_support/json/encoders
125
- - lib/active_support/json/encoders/core.rb
126
- - lib/active_support/json/encoders.rb
155
+ - lib/active_support/json/encoders/date.rb
156
+ - lib/active_support/json/encoders/date_time.rb
157
+ - lib/active_support/json/encoders/enumerable.rb
158
+ - lib/active_support/json/encoders/false_class.rb
159
+ - lib/active_support/json/encoders/hash.rb
160
+ - lib/active_support/json/encoders/nil_class.rb
161
+ - lib/active_support/json/encoders/numeric.rb
162
+ - lib/active_support/json/encoders/object.rb
163
+ - lib/active_support/json/encoders/regexp.rb
164
+ - lib/active_support/json/encoders/string.rb
165
+ - lib/active_support/json/encoders/symbol.rb
166
+ - lib/active_support/json/encoders/time.rb
167
+ - lib/active_support/json/encoders/true_class.rb
168
+ - lib/active_support/json/encoding.rb
169
+ - lib/active_support/json/variable.rb
127
170
  - lib/active_support/json.rb
128
171
  - lib/active_support/multibyte
129
172
  - lib/active_support/multibyte/chars.rb
@@ -136,22 +179,31 @@ files:
136
179
  - lib/active_support/multibyte.rb
137
180
  - lib/active_support/option_merger.rb
138
181
  - lib/active_support/ordered_options.rb
139
- - lib/active_support/reloadable.rb
182
+ - lib/active_support/test_case.rb
183
+ - lib/active_support/testing
184
+ - lib/active_support/testing/default.rb
185
+ - lib/active_support/testing.rb
140
186
  - lib/active_support/values
141
187
  - lib/active_support/values/time_zone.rb
142
188
  - lib/active_support/values/unicode_tables.dat
143
189
  - lib/active_support/vendor
144
- - lib/active_support/vendor/builder
145
- - lib/active_support/vendor/builder/blankslate.rb
146
- - lib/active_support/vendor/builder/xchar.rb
147
- - lib/active_support/vendor/builder/xmlbase.rb
148
- - lib/active_support/vendor/builder/xmlevents.rb
149
- - lib/active_support/vendor/builder/xmlmarkup.rb
150
- - lib/active_support/vendor/builder.rb
151
- - lib/active_support/vendor/xml_simple.rb
190
+ - lib/active_support/vendor/builder-2.1.2
191
+ - lib/active_support/vendor/builder-2.1.2/blankslate.rb
192
+ - lib/active_support/vendor/builder-2.1.2/builder
193
+ - lib/active_support/vendor/builder-2.1.2/builder/blankslate.rb
194
+ - lib/active_support/vendor/builder-2.1.2/builder/css.rb
195
+ - lib/active_support/vendor/builder-2.1.2/builder/xchar.rb
196
+ - lib/active_support/vendor/builder-2.1.2/builder/xmlbase.rb
197
+ - lib/active_support/vendor/builder-2.1.2/builder/xmlevents.rb
198
+ - lib/active_support/vendor/builder-2.1.2/builder/xmlmarkup.rb
199
+ - lib/active_support/vendor/builder-2.1.2/builder.rb
200
+ - lib/active_support/vendor/xml-simple-1.0.11
201
+ - lib/active_support/vendor/xml-simple-1.0.11/xmlsimple.rb
202
+ - lib/active_support/vendor.rb
152
203
  - lib/active_support/version.rb
153
204
  - lib/active_support/whiny_nil.rb
154
205
  - lib/active_support.rb
206
+ - lib/activesupport.rb
155
207
  test_files: []
156
208
 
157
209
  rdoc_options: []
@@ -1,84 +0,0 @@
1
- begin
2
- require 'simplecc'
3
- rescue LoadError
4
- class Continuation # :nodoc: # for RDoc
5
- end
6
- def Continuation.create(*args, &block) # :nodoc:
7
- cc = nil; result = callcc {|c| cc = c; block.call(cc) if block and args.empty?}
8
- result ||= args
9
- return *[cc, *result]
10
- end
11
- end
12
-
13
- class Binding; end # for RDoc
14
- # This method returns the binding of the method that called your
15
- # method. It will raise an Exception when you're not inside a method.
16
- #
17
- # It's used like this:
18
- # def inc_counter(amount = 1)
19
- # Binding.of_caller do |binding|
20
- # # Create a lambda that will increase the variable 'counter'
21
- # # in the caller of this method when called.
22
- # inc = eval("lambda { |arg| counter += arg }", binding)
23
- # # We can refer to amount from inside this block safely.
24
- # inc.call(amount)
25
- # end
26
- # # No other statements can go here. Put them inside the block.
27
- # end
28
- # counter = 0
29
- # 2.times { inc_counter }
30
- # counter # => 2
31
- #
32
- # Binding.of_caller must be the last statement in the method.
33
- # This means that you will have to put everything you want to
34
- # do after the call to Binding.of_caller into the block of it.
35
- # This should be no problem however, because Ruby has closures.
36
- # If you don't do this an Exception will be raised. Because of
37
- # the way that Binding.of_caller is implemented it has to be
38
- # done this way.
39
- def Binding.of_caller(&block)
40
- old_critical = Thread.critical
41
- Thread.critical = true
42
- count = 0
43
- cc, result, error, extra_data = Continuation.create(nil, nil)
44
- error.call if error
45
-
46
- tracer = lambda do |*args|
47
- type, context, extra_data = args[0], args[4], args
48
- if type == "return"
49
- count += 1
50
- # First this method and then calling one will return --
51
- # the trace event of the second event gets the context
52
- # of the method which called the method that called this
53
- # method.
54
- if count == 2
55
- # It would be nice if we could restore the trace_func
56
- # that was set before we swapped in our own one, but
57
- # this is impossible without overloading set_trace_func
58
- # in current Ruby.
59
- set_trace_func(nil)
60
- cc.call(eval("binding", context), nil, extra_data)
61
- end
62
- elsif type == "line" then
63
- nil
64
- elsif type == "c-return" and extra_data[3] == :set_trace_func then
65
- nil
66
- else
67
- set_trace_func(nil)
68
- error_msg = "Binding.of_caller used in non-method context or " +
69
- "trailing statements of method using it aren't in the block."
70
- cc.call(nil, lambda { raise(ArgumentError, error_msg) }, nil)
71
- end
72
- end
73
-
74
- unless result
75
- set_trace_func(tracer)
76
- return nil
77
- else
78
- Thread.critical = old_critical
79
- case block.arity
80
- when 1 then yield(result)
81
- else yield(result, extra_data)
82
- end
83
- end
84
- end
@@ -1,528 +0,0 @@
1
- # The Breakpoint library provides the convenience of
2
- # being able to inspect and modify state, diagnose
3
- # bugs all via IRB by simply setting breakpoints in
4
- # your applications by the call of a method.
5
- #
6
- # This library was written and is supported by me,
7
- # Florian Gross. I can be reached at flgr@ccan.de
8
- # and enjoy getting feedback about my libraries.
9
- #
10
- # The whole library (including breakpoint_client.rb
11
- # and binding_of_caller.rb) is licensed under the
12
- # same license that Ruby uses. (Which is currently
13
- # either the GNU General Public License or a custom
14
- # one that allows for commercial usage.) If you for
15
- # some good reason need to use this under another
16
- # license please contact me.
17
-
18
- require 'irb'
19
- require File.dirname(__FILE__) + '/binding_of_caller' unless defined? Binding.of_caller
20
- require 'drb'
21
- require 'drb/acl'
22
-
23
- module Breakpoint
24
- id = %q$Id: breakpoint.rb 92 2005-02-04 22:35:53Z flgr $
25
- Version = id.split(" ")[2].to_i
26
-
27
- extend self
28
-
29
- # This will pop up an interactive ruby session at a
30
- # pre-defined break point in a Ruby application. In
31
- # this session you can examine the environment of
32
- # the break point.
33
- #
34
- # You can get a list of variables in the context using
35
- # local_variables via +local_variables+. You can then
36
- # examine their values by typing their names.
37
- #
38
- # You can have a look at the call stack via +caller+.
39
- #
40
- # The source code around the location where the breakpoint
41
- # was executed can be examined via +source_lines+. Its
42
- # argument specifies how much lines of context to display.
43
- # The default amount of context is 5 lines. Note that
44
- # the call to +source_lines+ can raise an exception when
45
- # it isn't able to read in the source code.
46
- #
47
- # breakpoints can also return a value. They will execute
48
- # a supplied block for getting a default return value.
49
- # A custom value can be returned from the session by doing
50
- # +throw(:debug_return, value)+.
51
- #
52
- # You can also give names to break points which will be
53
- # used in the message that is displayed upon execution
54
- # of them.
55
- #
56
- # Here's a sample of how breakpoints should be placed:
57
- #
58
- # class Person
59
- # def initialize(name, age)
60
- # @name, @age = name, age
61
- # breakpoint("Person#initialize")
62
- # end
63
- #
64
- # attr_reader :age
65
- # def name
66
- # breakpoint("Person#name") { @name }
67
- # end
68
- # end
69
- #
70
- # person = Person.new("Random Person", 23)
71
- # puts "Name: #{person.name}"
72
- #
73
- # And here is a sample debug session:
74
- #
75
- # Executing break point "Person#initialize" at file.rb:4 in `initialize'
76
- # irb(#<Person:0x292fbe8>):001:0> local_variables
77
- # => ["name", "age", "_", "__"]
78
- # irb(#<Person:0x292fbe8>):002:0> [name, age]
79
- # => ["Random Person", 23]
80
- # irb(#<Person:0x292fbe8>):003:0> [@name, @age]
81
- # => ["Random Person", 23]
82
- # irb(#<Person:0x292fbe8>):004:0> self
83
- # => #<Person:0x292fbe8 @age=23, @name="Random Person">
84
- # irb(#<Person:0x292fbe8>):005:0> @age += 1; self
85
- # => #<Person:0x292fbe8 @age=24, @name="Random Person">
86
- # irb(#<Person:0x292fbe8>):006:0> exit
87
- # Executing break point "Person#name" at file.rb:9 in `name'
88
- # irb(#<Person:0x292fbe8>):001:0> throw(:debug_return, "Overriden name")
89
- # Name: Overriden name
90
- #
91
- # Breakpoint sessions will automatically have a few
92
- # convenience methods available. See Breakpoint::CommandBundle
93
- # for a list of them.
94
- #
95
- # Breakpoints can also be used remotely over sockets.
96
- # This is implemented by running part of the IRB session
97
- # in the application and part of it in a special client.
98
- # You have to call Breakpoint.activate_drb to enable
99
- # support for remote breakpoints and then run
100
- # breakpoint_client.rb which is distributed with this
101
- # library. See the documentation of Breakpoint.activate_drb
102
- # for details.
103
- def breakpoint(id = nil, context = nil, &block)
104
- callstack = caller
105
- callstack.slice!(0, 3) if callstack.first["breakpoint"]
106
- file, line, method = *callstack.first.match(/^(.+?):(\d+)(?::in `(.*?)')?/).captures
107
-
108
- message = "Executing break point " + (id ? "#{id.inspect} " : "") +
109
- "at #{file}:#{line}" + (method ? " in `#{method}'" : "")
110
-
111
- if context then
112
- return handle_breakpoint(context, message, file, line, &block)
113
- end
114
-
115
- Binding.of_caller do |binding_context|
116
- handle_breakpoint(binding_context, message, file, line, &block)
117
- end
118
- end
119
-
120
- module CommandBundle #:nodoc:
121
- # Proxy to a Breakpoint client. Lets you directly execute code
122
- # in the context of the client.
123
- class Client #:nodoc:
124
- def initialize(eval_handler) # :nodoc:
125
- eval_handler.untaint
126
- @eval_handler = eval_handler
127
- end
128
-
129
- instance_methods.each do |method|
130
- next if method[/^__.+__$/]
131
- undef_method method
132
- end
133
-
134
- # Executes the specified code at the client.
135
- def eval(code)
136
- @eval_handler.call(code)
137
- end
138
-
139
- # Will execute the specified statement at the client.
140
- def method_missing(method, *args, &block)
141
- if args.empty? and not block
142
- result = eval "#{method}"
143
- else
144
- # This is a bit ugly. The alternative would be using an
145
- # eval context instead of an eval handler for executing
146
- # the code at the client. The problem with that approach
147
- # is that we would have to handle special expressions
148
- # like "self", "nil" or constants ourself which is hard.
149
- remote = eval %{
150
- result = lambda { |block, *args| #{method}(*args, &block) }
151
- def result.call_with_block(*args, &block)
152
- call(block, *args)
153
- end
154
- result
155
- }
156
- remote.call_with_block(*args, &block)
157
- end
158
-
159
- return result
160
- end
161
- end
162
-
163
- # Returns the source code surrounding the location where the
164
- # breakpoint was issued.
165
- def source_lines(context = 5, return_line_numbers = false)
166
- lines = File.readlines(@__bp_file).map { |line| line.chomp }
167
-
168
- break_line = @__bp_line
169
- start_line = [break_line - context, 1].max
170
- end_line = break_line + context
171
-
172
- result = lines[(start_line - 1) .. (end_line - 1)]
173
-
174
- if return_line_numbers then
175
- return [start_line, break_line, result]
176
- else
177
- return result
178
- end
179
- end
180
-
181
- # Lets an object that will forward method calls to the breakpoint
182
- # client. This is useful for outputting longer things at the client
183
- # and so on. You can for example do these things:
184
- #
185
- # client.puts "Hello" # outputs "Hello" at client console
186
- # # outputs "Hello" into the file temp.txt at the client
187
- # client.File.open("temp.txt", "w") { |f| f.puts "Hello" }
188
- def client()
189
- if Breakpoint.use_drb? then
190
- sleep(0.5) until Breakpoint.drb_service.eval_handler
191
- Client.new(Breakpoint.drb_service.eval_handler)
192
- else
193
- Client.new(lambda { |code| eval(code, TOPLEVEL_BINDING) })
194
- end
195
- end
196
- end
197
-
198
- def handle_breakpoint(context, message, file = "", line = "", &block) # :nodoc:
199
- catch(:debug_return) do |value|
200
- eval(%{
201
- @__bp_file = #{file.inspect}
202
- @__bp_line = #{line}
203
- extend Breakpoint::CommandBundle
204
- extend DRbUndumped if self
205
- }, context) rescue nil
206
-
207
- if not use_drb? then
208
- puts message
209
- IRB.start(nil, IRB::WorkSpace.new(context))
210
- else
211
- @drb_service.add_breakpoint(context, message)
212
- end
213
-
214
- block.call if block
215
- end
216
- end
217
-
218
- # These exceptions will be raised on failed asserts
219
- # if Breakpoint.asserts_cause_exceptions is set to
220
- # true.
221
- class FailedAssertError < RuntimeError #:nodoc:
222
- end
223
-
224
- # This asserts that the block evaluates to true.
225
- # If it doesn't evaluate to true a breakpoint will
226
- # automatically be created at that execution point.
227
- #
228
- # You can disable assert checking in production
229
- # code by setting Breakpoint.optimize_asserts to
230
- # true. (It will still be enabled when Ruby is run
231
- # via the -d argument.)
232
- #
233
- # Example:
234
- # person_name = "Foobar"
235
- # assert { not person_name.nil? }
236
- #
237
- # Note: If you want to use this method from an
238
- # unit test, you will have to call it by its full
239
- # name, Breakpoint.assert.
240
- def assert(context = nil, &condition)
241
- return if Breakpoint.optimize_asserts and not $DEBUG
242
- return if yield
243
-
244
- callstack = caller
245
- callstack.slice!(0, 3) if callstack.first["assert"]
246
- file, line, method = *callstack.first.match(/^(.+?):(\d+)(?::in `(.*?)')?/).captures
247
-
248
- message = "Assert failed at #{file}:#{line}#{" in `#{method}'" if method}."
249
-
250
- if Breakpoint.asserts_cause_exceptions and not $DEBUG then
251
- raise(Breakpoint::FailedAssertError, message)
252
- end
253
-
254
- message += " Executing implicit breakpoint."
255
-
256
- if context then
257
- return handle_breakpoint(context, message, file, line)
258
- end
259
-
260
- Binding.of_caller do |context|
261
- handle_breakpoint(context, message, file, line)
262
- end
263
- end
264
-
265
- # Whether asserts should be ignored if not in debug mode.
266
- # Debug mode can be enabled by running ruby with the -d
267
- # switch or by setting $DEBUG to true.
268
- attr_accessor :optimize_asserts
269
- self.optimize_asserts = false
270
-
271
- # Whether an Exception should be raised on failed asserts
272
- # in non-$DEBUG code or not. By default this is disabled.
273
- attr_accessor :asserts_cause_exceptions
274
- self.asserts_cause_exceptions = false
275
- @use_drb = false
276
-
277
- attr_reader :drb_service # :nodoc:
278
-
279
- class DRbService # :nodoc:
280
- include DRbUndumped
281
-
282
- def initialize
283
- @handler = @eval_handler = @collision_handler = nil
284
-
285
- IRB.instance_eval { @CONF[:RC] = true }
286
- IRB.run_config
287
- end
288
-
289
- def collision
290
- sleep(0.5) until @collision_handler
291
-
292
- @collision_handler.untaint
293
-
294
- @collision_handler.call
295
- end
296
-
297
- def ping() end
298
-
299
- def add_breakpoint(context, message)
300
- workspace = IRB::WorkSpace.new(context)
301
- workspace.extend(DRbUndumped)
302
-
303
- sleep(0.5) until @handler
304
-
305
- @handler.untaint
306
- @handler.call(workspace, message)
307
- end
308
-
309
- attr_accessor :handler, :eval_handler, :collision_handler
310
- end
311
-
312
- # Will run Breakpoint in DRb mode. This will spawn a server
313
- # that can be attached to via the breakpoint-client command
314
- # whenever a breakpoint is executed. This is useful when you
315
- # are debugging CGI applications or other applications where
316
- # you can't access debug sessions via the standard input and
317
- # output of your application.
318
- #
319
- # You can specify an URI where the DRb server will run at.
320
- # This way you can specify the port the server runs on. The
321
- # default URI is druby://localhost:42531.
322
- #
323
- # Please note that breakpoints will be skipped silently in
324
- # case the DRb server can not spawned. (This can happen if
325
- # the port is already used by another instance of your
326
- # application on CGI or another application.)
327
- #
328
- # Also note that by default this will only allow access
329
- # from localhost. You can however specify a list of
330
- # allowed hosts or nil (to allow access from everywhere).
331
- # But that will still not protect you from somebody
332
- # reading the data as it goes through the net.
333
- #
334
- # A good approach for getting security and remote access
335
- # is setting up an SSH tunnel between the DRb service
336
- # and the client. This is usually done like this:
337
- #
338
- # $ ssh -L20000:127.0.0.1:20000 -R10000:127.0.0.1:10000 example.com
339
- # (This will connect port 20000 at the client side to port
340
- # 20000 at the server side, and port 10000 at the server
341
- # side to port 10000 at the client side.)
342
- #
343
- # After that do this on the server side: (the code being debugged)
344
- # Breakpoint.activate_drb("druby://127.0.0.1:20000", "localhost")
345
- #
346
- # And at the client side:
347
- # ruby breakpoint_client.rb -c druby://127.0.0.1:10000 -s druby://127.0.0.1:20000
348
- #
349
- # Running through such a SSH proxy will also let you use
350
- # breakpoint.rb in case you are behind a firewall.
351
- #
352
- # Detailed information about running DRb through firewalls is
353
- # available at http://www.rubygarden.org/ruby?DrbTutorial
354
- def activate_drb(uri = nil, allowed_hosts = ['localhost', '127.0.0.1', '::1'],
355
- ignore_collisions = false)
356
-
357
- return false if @use_drb
358
-
359
- uri ||= 'druby://localhost:42531'
360
-
361
- if allowed_hosts then
362
- acl = ["deny", "all"]
363
-
364
- Array(allowed_hosts).each do |host|
365
- acl += ["allow", host]
366
- end
367
-
368
- DRb.install_acl(ACL.new(acl))
369
- end
370
-
371
- @use_drb = true
372
- @drb_service = DRbService.new
373
- did_collision = false
374
- begin
375
- @service = DRb.start_service(uri, @drb_service)
376
- rescue Errno::EADDRINUSE
377
- if ignore_collisions then
378
- nil
379
- else
380
- # The port is already occupied by another
381
- # Breakpoint service. We will try to tell
382
- # the old service that we want its port.
383
- # It will then forward that request to the
384
- # user and retry.
385
- unless did_collision then
386
- DRbObject.new(nil, uri).collision
387
- did_collision = true
388
- end
389
- sleep(10)
390
- retry
391
- end
392
- end
393
-
394
- return true
395
- end
396
-
397
- # Deactivates a running Breakpoint service.
398
- def deactivate_drb
399
- @service.stop_service unless @service.nil?
400
- @service = nil
401
- @use_drb = false
402
- @drb_service = nil
403
- end
404
-
405
- # Returns true when Breakpoints are used over DRb.
406
- # Breakpoint.activate_drb causes this to be true.
407
- def use_drb?
408
- @use_drb == true
409
- end
410
- end
411
-
412
- module IRB #:nodoc:
413
- class << self; remove_method :start; end
414
- def self.start(ap_path = nil, main_context = nil, workspace = nil)
415
- $0 = File::basename(ap_path, ".rb") if ap_path
416
-
417
- # suppress some warnings about redefined constants
418
- old_verbose, $VERBOSE = $VERBOSE, nil
419
- IRB.setup(ap_path)
420
- $VERBOSE = old_verbose
421
-
422
- if @CONF[:SCRIPT] then
423
- irb = Irb.new(main_context, @CONF[:SCRIPT])
424
- else
425
- irb = Irb.new(main_context)
426
- end
427
-
428
- if workspace then
429
- irb.context.workspace = workspace
430
- end
431
-
432
- @CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC]
433
- @CONF[:MAIN_CONTEXT] = irb.context
434
-
435
- old_sigint = trap("SIGINT") do
436
- begin
437
- irb.signal_handle
438
- rescue RubyLex::TerminateLineInput
439
- # ignored
440
- end
441
- end
442
-
443
- catch(:IRB_EXIT) do
444
- irb.eval_input
445
- end
446
- ensure
447
- trap("SIGINT", old_sigint)
448
- end
449
-
450
- class << self
451
- alias :old_CurrentContext :CurrentContext
452
- remove_method :CurrentContext
453
- end
454
- def IRB.CurrentContext
455
- if old_CurrentContext.nil? and Breakpoint.use_drb? then
456
- result = Object.new
457
- def result.last_value; end
458
- return result
459
- else
460
- old_CurrentContext
461
- end
462
- end
463
-
464
- class << self
465
- alias :old_parse_opts :parse_opts
466
- remove_method :parse_opts
467
- end
468
- def IRB.parse_opts() end
469
-
470
- class Context #:nodoc:
471
- alias :old_evaluate :evaluate
472
- def evaluate(line, line_no)
473
- if line.chomp == "exit" then
474
- exit
475
- else
476
- old_evaluate(line, line_no)
477
- end
478
- end
479
- end
480
-
481
- class WorkSpace #:nodoc:
482
- alias :old_evaluate :evaluate
483
-
484
- def evaluate(*args)
485
- if Breakpoint.use_drb? then
486
- result = old_evaluate(*args)
487
- if args[0] != :no_proxy and
488
- not [true, false, nil].include?(result)
489
- then
490
- result.extend(DRbUndumped) rescue nil
491
- end
492
- return result
493
- else
494
- old_evaluate(*args)
495
- end
496
- end
497
- end
498
-
499
- module InputCompletor #:nodoc:
500
- def self.eval(code, context, *more)
501
- # Big hack, this assumes that InputCompletor
502
- # will only call eval() when it wants code
503
- # to be executed in the IRB context.
504
- IRB.conf[:MAIN_CONTEXT].workspace.evaluate(:no_proxy, code, *more)
505
- end
506
- end
507
- end
508
-
509
- module DRb # :nodoc:
510
- class DRbObject #:nodoc:
511
- undef :inspect if method_defined?(:inspect)
512
- undef :clone if method_defined?(:clone)
513
- end
514
- end
515
-
516
- # See Breakpoint.breakpoint
517
- def breakpoint(id = nil, &block)
518
- Binding.of_caller do |context|
519
- Breakpoint.breakpoint(id, context, &block)
520
- end
521
- end
522
-
523
- # See Breakpoint.assert
524
- def assert(&block)
525
- Binding.of_caller do |context|
526
- Breakpoint.assert(context, &block)
527
- end
528
- end