Class: Rusty::DX

Inherits:
Object
  • Object
show all
Defined in:
lib/rusty/dx.rb

Overview

A flexible data object which may act either as a hash or an array. It automatically initialises as array or hash, when used in a context which requires one or the other usage.

Direct Known Subclasses

Scope

Defined Under Namespace

Classes: Dict, List

Constant Summary collapse

EXCLUSIVE_LIST_METHODS =

method_missing automatically sets up storage, and matches method names with hash keys (when in Dict mode)

When setting up storage for this object the storage type is determined by these conditions:

  • identifiers, as getters (i.e. with no arguments), result in Dict storage

  • identifiers, as setters (i.e. with one argument, ending in ‘=’), result in Dict storage

  • the [] and []= operators result in List storage, if the argument is an integer, else in Dict storage.

  • Methods that are only implemented in the List or Dict storage determine the storage type accordingly. These are set up automatically by evaluating List/Dict::DELEGATE_METHODS. For example, you cannot push (<<) into a Hash, nor you can’t ask an array for existence of a key?

List::DELEGATE_METHODS - Dict::DELEGATE_METHODS
EXCLUSIVE_DICT_METHODS =
Dict::DELEGATE_METHODS - List::DELEGATE_METHODS

Class Method Summary collapse

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(sym, *args, &block) ⇒ Object



103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/rusty/dx.rb', line 103

def method_missing(sym, *args, &block)
  # A number of missing methods try to initialize this object either as
  # a hash or an array, and then forward the message to storage.
  case sym
  when :[], :[]=
    raise "#{self.class.name}##{sym}: Missing argument" unless args.length >= 1
    return __storage(args.first.is_a?(Integer) ? List : Dict).send(sym, *args)
  when /^([_A-Za-z][_A-Za-z0-9]*)$/
    if args.length == 0 && block.nil?
      return __storage(Dict)[sym.to_s]
    end
  when /^([_A-Za-z][_A-Za-z0-9]*)=$/
    if args.length == 1 && block.nil?
      return __storage(Dict)[$1] = args.first
    end
  else
    return __storage(List).send sym, *args, &block  if EXCLUSIVE_LIST_METHODS.include?(sym)
    return __storage(Dict).send sym, *args, &block  if EXCLUSIVE_DICT_METHODS.include?(sym)
  end

  # -- we could not set up nor delegate to storage; run super instead
  #    (this will raise a unknown method exception.)
  super
end

Class Method Details

.to_ruby(object) ⇒ Object



64
65
66
# File 'lib/rusty/dx.rb', line 64

def self.to_ruby(object)
  object.is_a?(Rusty::DX) ? object.to_ruby : object
end

Instance Method Details

#dict?Boolean

Is this object in hash mode?

Returns:

  • (Boolean)


58
# File 'lib/rusty/dx.rb', line 58

def dict?; @storage.is_a?(Dict); end

#inspectObject



37
38
39
# File 'lib/rusty/dx.rb', line 37

def inspect
  "<#{@storage ? @storage.inspect : "nil"}>"
end

#list?Boolean

Is this object in list mode?

Returns:

  • (Boolean)


61
# File 'lib/rusty/dx.rb', line 61

def list?; @storage.is_a?(List); end

#to_rubyObject

convert into a ruby object



69
70
71
72
73
74
75
76
77
78
79
# File 'lib/rusty/dx.rb', line 69

def to_ruby
  case @storage
  when Dict
    items = @storage.inject([]) do |ary, (k, v)| 
      ary << k << Rusty::DX.to_ruby(v) 
    end
    Hash[*items]
  when List
    @storage.map { |v| Rusty::DX.to_ruby(v) }
  end
end