File: bag.rb

package info (click to toggle)
ruby-ox 2.14.23-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 3,504 kB
  • sloc: xml: 39,683; ansic: 9,626; ruby: 6,441; sh: 47; makefile: 2
file content (103 lines) | stat: -rw-r--r-- 3,562 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
module Ox
  # A generic class that is used only for storing attributes. It is the base
  # Class for auto-generated classes in the storage system. Instance variables
  # are added using the instance_variable_set() method. All instance variables
  # can be accessed using the variable name (without the @ prefix). No setters
  # are provided as the Class is intended for reading only.
  class Bag
    # The initializer can take multiple arguments in the form of key values
    # where the key is the variable name and the value is the variable
    # value. This is intended for testing purposes only.
    # - +args+ [Hash] instance variable symbols and their values
    #
    # *Example*
    #
    #  Ox::Bag.new(:@x => 42, :@y => 57)
    #
    def initialize(args={})
      args.each do |k, v|
        instance_variable_set(k, v)
      end
    end

    # Replaces the Object.respond_to?() method.
    # - +m+ [Symbol] method symbol
    # *return* [Boolean] true for any method that matches an instance variable
    # reader, otherwise false.
    def respond_to?(m)
      return true if super

      at_m = ('@' + m.to_s).to_sym
      instance_variables.include?(at_m)
    end

    # Handles requests for variable values. Others cause an Exception to be
    # raised.
    # - +m+ (Symbol) method symbol
    # *return* [Boolean] the value of the specified instance variable.
    #
    # _raise_ [ArgumentError] if an argument is given. Zero arguments expected.
    #
    # _raise_ [NoMethodError] if the instance variable is not defined.
    def method_missing(m, *args, &block)
      unless args.nil? or args.empty?
        raise ArgumentError.new("wrong number of arguments (#{args.size} for 0) to method #{m}")
      end

      at_m = ('@' + m.to_s).to_sym
      raise NoMethodError.new("undefined method #{m}", m) unless instance_variable_defined?(at_m)

      instance_variable_get(at_m)
    end

    # Replaces eql?() with something more reasonable for this Class.
    # - +other+ [Object] Object to compare self to
    # *return* [Boolean] true if each variable and value are the same, otherwise false.
    def eql?(other)
      return false if (other.nil? or self.class != other.class)

      ova = other.instance_variables
      iv = instance_variables
      return false if ova.size != iv.size

      iv.each do |vid|
        return false if instance_variable_get(vid) != other.instance_variable_get(vid)
      end
      true
    end
    alias == eql?

    # Define a new class based on the Ox::Bag class. This is used internally in
    # the Ox module and is available to service wrappers that receive XML
    # requests that include Objects of Classes not defined in the storage
    # process.
    # - +classname+ (String) Class name or symbol that includes Module names.
    # *return* [Object] an instance of the specified Class.
    #
    # _raise_ [NameError] if the classname is invalid.
    def self.define_class(classname)
      classname = classname.to_s unless classname.is_a?(String)
      tokens = classname.split('::').map { |n| n.to_sym }
      raise NameError.new("Invalid classname '#{classname}") if tokens.empty?

      m = Object
      tokens[0..-2].each do |sym|
        if m.const_defined?(sym)
          m = m.const_get(sym)
        else
          c = Module.new
          m.const_set(sym, c)
          m = c
        end
      end
      sym = tokens[-1]
      if m.const_defined?(sym)
        c = m.const_get(sym)
      else
        c = Class.new(Ox::Bag)
        m.const_set(sym, c)
      end
      c
    end
  end # Bag
end # Ox