Empact-roxml 2.5.1 → 2.5.2

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.
Files changed (42) hide show
  1. data/History.txt +25 -0
  2. data/Manifest.txt +0 -4
  3. data/README.rdoc +12 -2
  4. data/examples/posts.rb +1 -1
  5. data/examples/twitter.rb +1 -1
  6. data/lib/roxml.rb +59 -149
  7. data/lib/roxml/definition.rb +60 -150
  8. data/lib/roxml/extensions.rb +4 -1
  9. data/lib/roxml/extensions/array/conversions.rb +0 -23
  10. data/lib/roxml/extensions/deprecation.rb +1 -1
  11. data/lib/roxml/extensions/string.rb +0 -15
  12. data/lib/roxml/extensions/string/conversions.rb +0 -38
  13. data/lib/roxml/hash_definition.rb +5 -40
  14. data/lib/roxml/xml/references.rb +20 -8
  15. data/roxml.gemspec +4 -4
  16. data/spec/definition_spec.rb +120 -193
  17. data/spec/examples/library_spec.rb +8 -3
  18. data/spec/examples/post_spec.rb +1 -1
  19. data/spec/roxml_spec.rb +14 -14
  20. data/test/bugs/rexml_bugs.rb +1 -1
  21. data/test/mocks/dictionaries.rb +8 -7
  22. data/test/mocks/mocks.rb +19 -19
  23. data/test/test_helper.rb +1 -0
  24. data/test/unit/definition_test.rb +22 -96
  25. data/test/unit/deprecations_test.rb +1 -74
  26. data/test/unit/to_xml_test.rb +6 -6
  27. data/test/unit/xml_attribute_test.rb +1 -1
  28. data/test/unit/xml_block_test.rb +3 -3
  29. data/test/unit/xml_bool_test.rb +4 -4
  30. data/test/unit/xml_convention_test.rb +3 -3
  31. data/test/unit/xml_hash_test.rb +5 -14
  32. data/test/unit/xml_initialize_test.rb +2 -6
  33. data/test/unit/xml_name_test.rb +5 -24
  34. data/test/unit/xml_namespace_test.rb +2 -2
  35. data/test/unit/xml_object_test.rb +5 -5
  36. data/test/unit/xml_required_test.rb +1 -1
  37. data/test/unit/xml_text_test.rb +2 -2
  38. metadata +12 -17
  39. data/lib/roxml/extensions/active_support.rb +0 -54
  40. data/spec/string_spec.rb +0 -15
  41. data/test/release/dependencies_test.rb +0 -32
  42. data/test/unit/xml_construct_test.rb +0 -77
data/History.txt CHANGED
@@ -1,3 +1,28 @@
1
+ == 3.0 ???
2
+
3
+ * major enhancements
4
+
5
+ * Remove previously deprecated functionality
6
+ * Error on any unrecognized options
7
+ * Normalize hash declaration syntax:
8
+ * for :key => '@string', string is taken to be the :from argument
9
+ * for :key => {:from => '@string', :as => Type}, the arguments are just the same as a regular declaration
10
+
11
+ * minor enhancements
12
+
13
+ * Include 't' and 'f' in the list of possible boolean values, since rails uses them
14
+ * Remove :attrs hash syntax. Not particularly helpful & somewhat obfuscatory. Use :key, :value instead.
15
+ * Default attrs ending in '_at' to DateTime. This can be overriden via :as
16
+ * Default attrs ending in '_on' to Date. This can be overriden via :as
17
+
18
+ == 2.5.2 (March 12, 2009)
19
+
20
+ * minor enhancements
21
+
22
+ * Remove dependency on an Object#try which conflicted with ActiveSupport 2.3's version
23
+ * Document the :to_xml option for attr references
24
+ * Require active_support directly, as it's less brittle and plays nicer with other libraries
25
+
1
26
  == 2.5.1 (March 2, 2009)
2
27
 
3
28
  * minor enhancements
data/Manifest.txt CHANGED
@@ -21,7 +21,6 @@ examples/xml/twitter.xml
21
21
  lib/roxml.rb
22
22
  lib/roxml/definition.rb
23
23
  lib/roxml/extensions.rb
24
- lib/roxml/extensions/active_support.rb
25
24
  lib/roxml/extensions/array.rb
26
25
  lib/roxml/extensions/array/conversions.rb
27
26
  lib/roxml/extensions/deprecation.rb
@@ -46,7 +45,6 @@ spec/roxml_spec.rb
46
45
  spec/shared_specs.rb
47
46
  spec/spec.opts
48
47
  spec/spec_helper.rb
49
- spec/string_spec.rb
50
48
  spec/xml/parser_spec.rb
51
49
  tasks/rspec.rake
52
50
  tasks/test.rake
@@ -83,7 +81,6 @@ test/fixtures/person_with_guarded_mothers.xml
83
81
  test/fixtures/person_with_mothers.xml
84
82
  test/mocks/dictionaries.rb
85
83
  test/mocks/mocks.rb
86
- test/release/dependencies_test.rb
87
84
  test/test_helper.rb
88
85
  test/unit/definition_test.rb
89
86
  test/unit/deprecations_test.rb
@@ -91,7 +88,6 @@ test/unit/to_xml_test.rb
91
88
  test/unit/xml_attribute_test.rb
92
89
  test/unit/xml_block_test.rb
93
90
  test/unit/xml_bool_test.rb
94
- test/unit/xml_construct_test.rb
95
91
  test/unit/xml_convention_test.rb
96
92
  test/unit/xml_hash_test.rb
97
93
  test/unit/xml_initialize_test.rb
data/README.rdoc CHANGED
@@ -1,5 +1,15 @@
1
- ROXML Ruby Object to XML mapping library. For more information
2
- visit http://roxml.rubyforge.org
1
+ ROXML Ruby Object to XML mapping library.
2
+
3
+ For more information visit:
4
+
5
+ http://roxml.rubyforge.org/rdoc/
6
+ http://empact.github.com/roxml/
7
+ http://rubyforge.org/projects/roxml/
8
+
9
+ Progress on this project is (more or less) tracked at:
10
+
11
+ http://www.pivotaltracker.com/project/4109
12
+
3
13
 
4
14
  =Quick Start Guide
5
15
 
data/examples/posts.rb CHANGED
@@ -8,7 +8,7 @@ class Post
8
8
  xml_reader :hash, :from => :attr
9
9
  xml_reader :description, :from => :attr
10
10
  xml_reader :tag, :from => :attr
11
- xml_reader :time, :from => :attr, :as => DateTime
11
+ xml_reader :created_at, :from => '@time'
12
12
  xml_reader :others, :from => :attr, :as => Integer
13
13
  xml_reader :extended, :from => :attr
14
14
  end
data/examples/twitter.rb CHANGED
@@ -21,7 +21,7 @@ class Status
21
21
 
22
22
  xml_reader :id, :as => Integer
23
23
  xml_reader :text
24
- xml_reader :created_at, :as => Time
24
+ xml_reader :created_at # This defaults to :as => DateTime, due to the '_at'
25
25
  xml_reader :source
26
26
  xml_reader :truncated?
27
27
  xml_reader :in_reply_to_status_id, :as => Integer
data/lib/roxml.rb CHANGED
@@ -8,84 +8,26 @@ require 'uri'
8
8
  end
9
9
 
10
10
  module ROXML # :nodoc:
11
- VERSION = '2.5.1'
11
+ VERSION = '2.5.2'
12
12
 
13
13
  def self.included(base) # :nodoc:
14
- base.extend ClassMethods::Accessors,
15
- ClassMethods::Declarations,
16
- ClassMethods::Operations
17
14
  base.class_eval do
18
- include InstanceMethods::Accessors,
19
- InstanceMethods::Construction,
20
- InstanceMethods::Conversions
15
+ extend ClassMethods::Accessors,
16
+ ClassMethods::Declarations,
17
+ ClassMethods::Operations
18
+ include InstanceMethods
21
19
  end
22
20
  end
23
21
 
24
22
  module InstanceMethods # :nodoc:
25
- # Instance method equivalents of the Class method accessors
26
- module Accessors # :nodoc:all
27
- # Provides access to ROXML::ClassMethods::Accessors::tag_name directly from an instance of a ROXML class
28
- def tag_name
29
- self.class.tag_name
30
- end
31
- deprecate :tag_name => 'use class.tag_name instead'
32
-
33
- # Provides access to ROXML::ClassMethods::Accessors::tag_refs directly from an instance of a ROXML class
34
- def tag_refs
35
- self.class.tag_refs_without_deprecation
36
- end
37
- deprecate :tag_refs => :roxml_attrs
38
- end
39
-
40
- module Construction
41
- # xml_initialize is called at the end of the #from_xml operation on objects
42
- # where xml_construct is not in place. Override xml_initialize in order to establish
43
- # post-import behavior. For example, you can use xml_initialize to map xml attribute
44
- # values into the object standard initialize function, thus enabling a ROXML object
45
- # to freely be either xml-backed or instantiated directly via #new.
46
- # An example of this follows:
47
- #
48
- # class Measurement
49
- # include ROXML
50
- #
51
- # xml_reader :units, :from => :attr
52
- # xml_reader :value, :from => :content
53
- #
54
- # def xml_initialize
55
- # # the object is instantiated, and all xml attributes are imported
56
- # # and available, i.e., value and units below are the same value and units
57
- # # found in the xml via the xml_reader declarations above.
58
- # initialize(value, units)
59
- # end
60
- #
61
- # def initialize(value, units = 'pixels')
62
- # @value = Float(value)
63
- # @units = units.to_s
64
- # if @units.starts_with? 'hundredths-'
65
- # @value /= 100
66
- # @units = @units.split('hundredths-')[1]
67
- # end
68
- # end
69
- # end
70
- #
71
- # #xml_initialize may be written to take arguments, in which case extra arguments
72
- # from from_xml will be passed into the function.
73
- #
74
- def xml_initialize # :nodoc:
75
- end
76
- deprecate :xml_initialize => :after_parse
77
- end
78
-
79
- module Conversions
80
- # Returns a LibXML::XML::Node or a REXML::Element representing this object
81
- def to_xml(name = nil)
82
- returning XML::Node.new((name || self.class.tag_name).to_s) do |root|
83
- self.class.roxml_attrs.each do |attr|
84
- ref = attr.to_ref(self)
85
- v = ref.to_xml
86
- unless v.nil?
87
- ref.update_xml(root, v)
88
- end
23
+ # Returns a LibXML::XML::Node or a REXML::Element representing this object
24
+ def to_xml(name = self.class.tag_name)
25
+ returning XML::Node.new(name.to_s) do |root|
26
+ self.class.roxml_attrs.each do |attr|
27
+ ref = attr.to_ref(self)
28
+ value = ref.to_xml
29
+ unless value.nil?
30
+ ref.update_xml(root, value)
89
31
  end
90
32
  end
91
33
  end
@@ -169,13 +111,19 @@ module ROXML # :nodoc:
169
111
  # but in this case an underscored version of the name is applied, for convenience.
170
112
  def xml_convention(to_proc_able = nil, &block)
171
113
  raise ArgumentError, "conventions are already set" if @roxml_naming_convention
172
- raise ArgumentError, "only one conventions can be set" if to_proc_able.respond_to?(:to_proc) && block_given?
173
- @roxml_naming_convention = to_proc_able.try(:to_proc)
174
- @roxml_naming_convention = block if block_given?
114
+ @roxml_naming_convention =
115
+ if to_proc_able
116
+ raise ArgumentError, "only one conventions can be set" if block_given?
117
+ to_proc_able.to_proc
118
+ elsif block_given?
119
+ block
120
+ end
175
121
  end
176
122
 
177
123
  def roxml_naming_convention # :nodoc:
178
- (@roxml_naming_convention || superclass.try(:roxml_naming_convention)).freeze
124
+ (@roxml_naming_convention || begin
125
+ superclass.roxml_naming_convention if superclass.respond_to?(:roxml_naming_convention)
126
+ end).freeze
179
127
  end
180
128
 
181
129
  # Declares a reference to a certain xml element, whether an attribute, a node,
@@ -269,7 +217,7 @@ module ROXML # :nodoc:
269
217
  #
270
218
  # xml_reader :counts, :as => [Integer]
271
219
  #
272
- # Even an array of :text nodes can be specified with :as => []
220
+ # Even an array of text nodes can be specified with :as => []
273
221
  #
274
222
  # xml_reader :quotes, :as => []
275
223
  #
@@ -320,7 +268,7 @@ module ROXML # :nodoc:
320
268
  # a collection of key-value pairs represented in your xml. You create a hash declaration by
321
269
  # passing a hash mapping as the type argument. A few examples:
322
270
  #
323
- # ===== Hash of :texts
271
+ # ===== Hash of element contents
324
272
  # For xml such as this:
325
273
  #
326
274
  # <dictionary>
@@ -439,30 +387,30 @@ module ROXML # :nodoc:
439
387
  # [:else] Default value for attribute, if missing from the xml on .from_xml
440
388
  # [:required] If true, throws RequiredElementMissing when the element isn't present
441
389
  # [:frozen] If true, all results are frozen (using #freeze) at parse-time.
442
- # [:cdata] True for values which should be input from or output as cdata elements
443
- #
444
- def xml_attr(sym, type_and_or_opts = nil, opts = nil, &block)
445
- returning Definition.new(sym, *[type_and_or_opts, opts].compact, &block) do |attr|
446
- if roxml_attrs.map(&:accessor).include? attr.accessor
447
- raise "Accessor #{attr.accessor} is already defined as XML accessor in class #{self.name}"
390
+ # [:cdata] true for values which should be input from or output as cdata elements
391
+ # [:to_xml] this proc is applied to the attributes value outputting the instance via #to_xml
392
+ #
393
+ def xml_attr(*syms, &block)
394
+ opts = syms.extract_options!
395
+ syms.map do |sym|
396
+ returning Definition.new(sym, opts, &block) do |attr|
397
+ if roxml_attrs.map(&:accessor).include? attr.accessor
398
+ raise "Accessor #{attr.accessor} is already defined as XML accessor in class #{self.name}"
399
+ end
400
+ @roxml_attrs << attr
448
401
  end
449
- @roxml_attrs << attr
450
402
  end
451
403
  end
452
404
 
453
- def xml(sym, writable = false, type_and_or_opts = nil, opts = nil, &block) #:nodoc:
454
- send(writable ? :xml_accessor : :xml_reader, sym, type_and_or_opts, opts, &block)
455
- end
456
- deprecate :xml => "use xml_attr, xml_reader, or xml_accessor instead"
457
-
458
405
  # Declares a read-only xml reference. See xml_attr for details.
459
406
  #
460
407
  # Note that while xml_reader does not create a setter for this attribute,
461
408
  # its value can be modified indirectly via methods. For more complete
462
409
  # protection, consider the :frozen option.
463
- def xml_reader(sym, type_and_or_opts = nil, opts = nil, &block)
464
- attr = xml_attr sym, type_and_or_opts, opts, &block
465
- add_reader(attr)
410
+ def xml_reader(*syms, &block)
411
+ xml_attr(*syms, &block).each do |attr|
412
+ add_reader(attr)
413
+ end
466
414
  end
467
415
 
468
416
  # Declares a writable xml reference. See xml_attr for details.
@@ -470,45 +418,22 @@ module ROXML # :nodoc:
470
418
  # Note that while xml_accessor does create a setter for this attribute,
471
419
  # you can use the :frozen option to prevent its value from being
472
420
  # modified indirectly via methods.
473
- def xml_accessor(sym, type_and_or_opts = nil, opts = nil, &block)
474
- attr = xml_attr sym, type_and_or_opts, opts, &block
475
- add_reader(attr)
476
- attr_writer(attr.variable_name)
477
- end
478
-
479
- # This method is deprecated, please use xml_initialize instead
480
- def xml_construct(*args) # :nodoc:
481
- present_tags = tag_refs_without_deprecation.map(&:accessor)
482
- missing_tags = args - present_tags
483
- unless missing_tags.empty?
484
- raise ArgumentError, "All construction tags must be declared first using xml, " +
485
- "xml_reader, or xml_accessor. #{missing_tags.join(', ')} is missing. " +
486
- "#{present_tags.join(', ')} are declared."
421
+ def xml_accessor(*syms, &block)
422
+ xml_attr(*syms, &block).each do |attr|
423
+ add_reader(attr)
424
+ attr_writer(attr.attr_name)
487
425
  end
488
- @xml_construction_args = args
489
426
  end
490
- deprecate :xml_construct => :xml_initialize
491
427
 
492
428
  private
493
429
  def add_reader(attr)
494
430
  define_method(attr.accessor) do
495
- instance_variable_get("@#{attr.variable_name}")
431
+ instance_variable_get(attr.instance_variable_name)
496
432
  end
497
433
  end
498
434
  end
499
435
 
500
436
  module Accessors
501
- def xml_construction_args # :nodoc:
502
- @xml_construction_args ||= []
503
- end
504
- deprecate :xml_construction_args
505
-
506
- # A helper which enables us to detect when the xml_name has been explicitly set
507
- def xml_name? #:nodoc:
508
- @roxml_tag_name
509
- end
510
- deprecate :xml_name?
511
-
512
437
  # Returns the tag name (also known as xml_name) of the class.
513
438
  # If no tag name is set with xml_name method, returns default class name
514
439
  # in lowercase.
@@ -526,24 +451,23 @@ module ROXML # :nodoc:
526
451
  end
527
452
 
528
453
  def roxml_tag_name # :nodoc:
529
- @roxml_tag_name || superclass.try(:roxml_tag_name)
454
+ @roxml_tag_name || begin
455
+ superclass.roxml_tag_name if superclass.respond_to?(:roxml_tag_name)
456
+ end
530
457
  end
531
458
 
532
459
  def roxml_namespace # :nodoc:
533
- @roxml_namespace || superclass.try(:roxml_namespace)
460
+ @roxml_namespace || begin
461
+ superclass.roxml_namespace if superclass.respond_to?(:roxml_namespace)
462
+ end
534
463
  end
535
464
 
536
465
  # Returns array of internal reference objects, such as attributes
537
466
  # and composed XML objects
538
467
  def roxml_attrs
539
468
  @roxml_attrs ||= []
540
- (@roxml_attrs + (superclass.try(:roxml_attrs) || [])).freeze
541
- end
542
-
543
- def tag_refs # :nodoc:
544
- roxml_attrs.map {|a| a.to_ref(nil) }
469
+ (@roxml_attrs + (superclass.respond_to?(:roxml_attrs) ? superclass.roxml_attrs : [])).freeze
545
470
  end
546
- deprecate :tag_refs => :roxml_attrs
547
471
  end
548
472
 
549
473
  module Operations
@@ -569,32 +493,18 @@ module ROXML # :nodoc:
569
493
  def from_xml(data, *initialization_args)
570
494
  xml = XML::Node.from(data)
571
495
 
572
- unless xml_construction_args_without_deprecation.empty?
573
- args = xml_construction_args_without_deprecation.map do |arg|
574
- roxml_attrs.find {|attr| attr.accessor == arg }
575
- end.map {|attr| attr.to_ref(self).value_in(xml) }
576
- new(*args)
577
- else
578
- returning new(*initialization_args) do |inst|
579
- roxml_attrs.each do |attr|
580
- value = attr.to_ref(inst).value_in(xml)
581
- setter = :"#{attr.variable_name}="
582
- inst.respond_to?(setter) \
583
- ? inst.send(setter, value) \
584
- : inst.instance_variable_set("@#{attr.variable_name}", value)
585
- end
586
- inst.try(:after_parse)
496
+ returning new(*initialization_args) do |inst|
497
+ roxml_attrs.each do |attr|
498
+ value = attr.to_ref(inst).value_in(xml)
499
+ inst.respond_to?(attr.setter) \
500
+ ? inst.send(attr.setter, value) \
501
+ : inst.instance_variable_set(attr.instance_variable_name, value)
587
502
  end
503
+ inst.send(:after_parse) if inst.respond_to?(:after_parse, true)
588
504
  end
589
505
  rescue ArgumentError => e
590
506
  raise e, e.message + " for class #{self}"
591
507
  end
592
-
593
- # Deprecated in favor of #from_xml
594
- def parse(data) # :nodoc:
595
- from_xml(data)
596
- end
597
- deprecate :parse => :from_xml
598
508
  end
599
509
  end
600
510
  end
@@ -12,47 +12,39 @@ end
12
12
 
13
13
  module ROXML
14
14
  class Definition # :nodoc:
15
- attr_reader :name, :type, :wrapper, :hash, :blocks, :accessor, :to_xml
15
+ attr_reader :name, :type, :wrapper, :hash, :blocks, :accessor, :to_xml, :attr_name
16
16
  bool_attr_reader :name_explicit, :array, :cdata, :required, :frozen
17
17
 
18
- class << self
19
- def silence_xml_name_warning?
20
- @silence_xml_name_warning || (ROXML.const_defined?('SILENCE_XML_NAME_WARNING') && ROXML::SILENCE_XML_NAME_WARNING)
21
- end
22
-
23
- def silence_xml_name_warning!
24
- @silence_xml_name_warning = true
25
- end
26
- end
27
-
28
- def initialize(sym, *args, &block)
29
- @accessor = sym
30
- if @accessor.to_s.ends_with?('_on')
31
- ActiveSupport::Deprecation.warn "In 3.0, attributes with names ending with _on will default to Date type, rather than :text"
32
- end
33
- if @accessor.to_s.ends_with?('_at')
34
- ActiveSupport::Deprecation.warn "In 3.0, attributes with names ending with _at will default to DateTime type, rather than :text"
35
- end
18
+ def initialize(sym, opts = {}, &block)
19
+ opts.assert_valid_keys(:from, :in, :as,
20
+ :else, :required, :frozen, :cdata, :to_xml)
21
+ @default = opts.delete(:else)
22
+ @to_xml = opts.delete(:to_xml)
23
+ @name_explicit = opts.has_key?(:from) && opts[:from].is_a?(String)
24
+ @cdata = opts.delete(:cdata)
25
+ @required = opts.delete(:required)
26
+ @frozen = opts.delete(:frozen)
27
+ @wrapper = opts.delete(:in)
36
28
 
37
- opts = extract_options!(args)
38
- opts[:as] ||= :bool if @accessor.to_s.ends_with?('?')
29
+ @accessor = sym.to_s
30
+ opts[:as] ||=
31
+ if @accessor.ends_with?('?')
32
+ :bool
33
+ elsif @accessor.ends_with?('_on')
34
+ Date
35
+ elsif @accessor.ends_with?('_at')
36
+ DateTime
37
+ end
39
38
 
40
- @array = opts[:as].is_a?(Array) || extract_from_as(opts, :array, "Please use [] around your usual type declaration")
39
+ @array = opts[:as].is_a?(Array)
41
40
  @blocks = collect_blocks(block, opts[:as])
42
41
 
43
- if opts.has_key?(:readonly)
44
- raise ArgumentError, "There is no 'readonly' option. You probably mean to use :frozen => true"
45
- end
46
-
47
- @type = extract_type(args, opts)
48
- if @type.try(:xml_name_without_deprecation?)
49
- unless self.class.silence_xml_name_warning?
50
- warn "WARNING: As of 2.3, a breaking change has been in the naming of sub-objects. " +
51
- "ROXML now considers the xml_name of the sub-object before falling back to the accessor name of the parent. " +
52
- "Use :from on the parent declaration to override this behavior. Set ROXML::SILENCE_XML_NAME_WARNING to avoid this message."
53
- self.class.silence_xml_name_warning!
54
- end
55
- opts[:from] ||= @type.tag_name
42
+ @type = extract_type(opts[:as])
43
+ if @type.respond_to?(:roxml_tag_name)
44
+ # "WARNING: As of 2.3, a breaking change has been in the naming of sub-objects. " +
45
+ # "ROXML now considers the xml_name of the sub-object before falling back to the accessor name of the parent. " +
46
+ # "Use :from on the parent declaration to override this behavior. Set ROXML::SILENCE_XML_NAME_WARNING to avoid this message."
47
+ opts[:from] ||= @type.roxml_tag_name
56
48
  end
57
49
 
58
50
  if opts[:from] == :content
@@ -62,12 +54,15 @@ module ROXML
62
54
  elsif opts[:from] == :attr
63
55
  @type = :attr
64
56
  opts[:from] = nil
57
+ elsif opts[:from] == :name
58
+ opts[:from] = '*'
65
59
  elsif opts[:from].to_s.starts_with?('@')
66
60
  @type = :attr
67
61
  opts[:from].sub!('@', '')
68
62
  end
69
63
 
70
- @name = (opts[:from] || variable_name).to_s
64
+ @attr_name = accessor.to_s.chomp('?')
65
+ @name = (opts[:from] || @attr_name).to_s
71
66
  @name = @name.singularize if hash? || array?
72
67
  if hash? && (hash.key.name? || hash.value.name?)
73
68
  @name = '*'
@@ -76,8 +71,12 @@ module ROXML
76
71
  raise ArgumentError, "Can't specify both :else default and :required" if required? && @default
77
72
  end
78
73
 
79
- def variable_name
80
- accessor.to_s.chomp('?')
74
+ def instance_variable_name
75
+ :"@#{attr_name}"
76
+ end
77
+
78
+ def setter
79
+ :"#{attr_name}="
81
80
  end
82
81
 
83
82
  def hash
@@ -127,23 +126,11 @@ module ROXML
127
126
  array ? results : results.first
128
127
  end
129
128
 
130
- BLOCK_TO_FLOAT = lambda do |val|
131
- all(val) do |v|
132
- Float(v) unless v.blank?
133
- end
134
- end
135
-
136
- BLOCK_TO_INT = lambda do |val|
137
- all(val) do |v|
138
- Integer(v) unless v.blank?
139
- end
140
- end
141
-
142
129
  def self.fetch_bool(value, default)
143
- value = value.try(:downcase)
144
- if %w{true yes 1}.include? value
130
+ value = value.to_s.downcase
131
+ if %w{true yes 1 t}.include? value
145
132
  true
146
- elsif %w{false no 0}.include? value
133
+ elsif %w{false no 0 f}.include? value
147
134
  false
148
135
  else
149
136
  default
@@ -152,10 +139,16 @@ module ROXML
152
139
 
153
140
  CORE_BLOCK_SHORTHANDS = {
154
141
  # Core Shorthands
155
- :integer => BLOCK_TO_INT, # deprecated
156
- Integer => BLOCK_TO_INT,
157
- :float => BLOCK_TO_FLOAT, # deprecated
158
- Float => BLOCK_TO_FLOAT,
142
+ Integer => lambda do |val|
143
+ all(val) do |v|
144
+ Integer(v) unless v.blank?
145
+ end
146
+ end,
147
+ Float => lambda do |val|
148
+ all(val) do |v|
149
+ Float(v) unless v.blank?
150
+ end
151
+ end,
159
152
  Fixnum => lambda do |val|
160
153
  all(val) do |v|
161
154
  v.to_i unless v.blank?
@@ -203,9 +196,6 @@ module ROXML
203
196
  end
204
197
 
205
198
  def collect_blocks(block, as)
206
- ActiveSupport::Deprecation.warn ":as => :float is deprecated. Use :as => Float instead" if as == :float
207
- ActiveSupport::Deprecation.warn ":as => :integer is deprecated. Use :as => Integer instead" if as == :integer
208
-
209
199
  if as.is_a?(Array)
210
200
  unless as.one? || as.empty?
211
201
  raise ArgumentError, "multiple :as types (#{as.map(&:inspect).join(', ')}) is not supported. Use a block if you want more complicated behavior."
@@ -220,104 +210,24 @@ module ROXML
220
210
  as = (block ? :bool_combined : :bool_standalone)
221
211
  end
222
212
  as = self.class.block_shorthands.fetch(as) do
223
- unless as.respond_to?(:from_xml) || as.try(:first).respond_to?(:from_xml) || (as.is_a?(Hash) && !(as.keys & HASH_KEYS).empty?)
224
- ActiveSupport::Deprecation.warn "#{as.inspect} is not a valid type declaration. ROXML will raise in this case in version 3.0" unless as.nil?
213
+ unless as.respond_to?(:from_xml) || (as.respond_to?(:first) && as.first.respond_to?(:from_xml)) || (as.is_a?(Hash) && !(as.keys & [:key, :value]).empty?)
214
+ raise ArgumentError, "Invalid :as argument #{as}" unless as.nil?
225
215
  end
226
216
  nil
227
217
  end
228
218
  [as, block].compact
229
219
  end
230
220
 
231
- def extract_options!(args)
232
- opts = args.extract_options!
233
- unless (opts.keys & HASH_KEYS).empty?
234
- args.push(opts)
235
- opts = {}
236
- end
237
-
238
- @default = opts.delete(:else)
239
- @to_xml = opts.delete(:to_xml)
240
- @name_explicit = opts.has_key?(:from) && opts[:from].is_a?(String)
241
- @cdata = opts.delete(:cdata)
242
- @required = opts.delete(:required)
243
- @frozen = opts.delete(:frozen)
244
- @wrapper = opts.delete(:in)
245
-
246
- @cdata ||= extract_from_as(opts, :cdata, "Please use :cdata => true")
247
-
248
- if opts[:as].is_a?(Array) && opts[:as].size > 1
249
- ActiveSupport::Deprecation.warn ":as should point to a single item. #{opts[:as].join(', ')} should be declared some other way."
250
- end
251
-
252
- opts
253
- end
254
-
255
- def extract_from_as(opts, entry, message)
256
- # remove with deprecateds...
257
- if [*opts[:as]].include?(entry)
258
- ActiveSupport::Deprecation.warn ":as => #{entry.inspect} is deprecated. #{message}"
259
- if opts[:as] == entry
260
- opts[:as] = nil
261
- else
262
- opts[:as].delete(entry)
263
- end
264
- true
265
- end
266
- end
267
-
268
- def extract_type(args, opts)
269
- types = (opts.keys & TYPE_KEYS)
270
- # type arg
271
- if args.one? && types.empty?
272
- type = args.first
273
- if type.is_a? Array
274
- ActiveSupport::Deprecation.warn "Array declarations should be passed as the :as parameter, for future release."
275
- @array = true
276
- return type.first || :text
277
- elsif type.is_a? Hash
278
- ActiveSupport::Deprecation.warn "Hash declarations should be passed as the :as parameter, for future release."
279
- return HashDefinition.new(type)
280
- elsif type == :content
281
- ActiveSupport::Deprecation.warn ":content as a type declaration is deprecated. Use :from => '.' or :from => :content instead"
282
- opts[:from] = :content
283
- return :text
284
- elsif type == :attr
285
- ActiveSupport::Deprecation.warn ":attr as a type declaration is deprecated. Use :from => '@attr_name' or :from => :attr instead"
286
- opts[:from].sub!('@', '') if opts[:from].to_s.starts_with?('@') # this is added back next line...
287
- opts[:from] = opts[:from].nil? ? :attr : "@#{opts[:from]}"
288
- return :attr
289
- else
290
- ActiveSupport::Deprecation.warn "Type declarations should be passed as the :as parameter, for future release."
291
- return type
292
- end
293
- end
294
-
295
- unless args.empty?
296
- raise ArgumentError, "too many arguments (#{(args + types).join(', ')}). Should be name, type, and " +
297
- "an options hash, with the type and options optional"
298
- end
299
-
300
- if opts[:as].is_a?(Hash)
301
- return HashDefinition.new(opts[:as])
302
- elsif opts[:as].respond_to?(:from_xml)
303
- return opts[:as]
304
- elsif opts[:as].is_a?(Array) && opts[:as].first.respond_to?(:from_xml)
221
+ def extract_type(as)
222
+ if as.is_a?(Hash)
223
+ return HashDefinition.new(as)
224
+ elsif as.respond_to?(:from_xml)
225
+ return as
226
+ elsif as.is_a?(Array) && as.first.respond_to?(:from_xml)
305
227
  @array = true
306
- return opts[:as].first
307
- end
308
-
309
- # type options
310
- if types.one?
311
- opts[:from] = opts.delete(types.first)
312
- if opts[:from] == :content
313
- opts[:from] = 'content'
314
- ActiveSupport::Deprecation.warn ":content is now a reserved as an alias for '.'. Use the string 'content' instead"
315
- end
316
- types.first
317
- elsif types.empty?
318
- :text
228
+ return as.first
319
229
  else
320
- raise ArgumentError, "more than one type option specified: #{types.join(', ')}"
230
+ :text
321
231
  end
322
232
  end
323
233
  end