Class: Outline

Inherits:
Object
  • Object
show all
Includes:
MetaTools
Defined in:
lib/outline.rb

Constant Summary collapse

VERSION =
'0.2.0'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts = {}, &blk) ⇒ Outline

Returns a new instance of Outline.

Raises:

  • (TypeError)


32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/outline.rb', line 32

def initialize(opts={}, &blk)
  raise(TypeError, "opts must respond to :to_hash or be nil") unless opts.nil? || opts.respond_to?(:to_hash)
  raise(TypeError, "opts[:data] must respond to :to_h or :to_hash or be nil") unless opts[:data].nil? || opts[:data].respond_to?(:to_hash) || opts[:data].respond_to?(:to_h)
  
  opts = opts.to_hash
  data = opts[:data].respond_to?(:to_hash) ? opts[:data].to_hash : opts[:data].to_h unless opts[:data].nil?
  
  @parent = opts[:parent]
  @data = data
  @methods = []
  
  instance_eval(&blk) unless blk.nil?
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(meth, *args, &blk) ⇒ Object



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
# File 'lib/outline.rb', line 46

def method_missing(meth, *args, &blk)
  meth = meth.to_s.gsub(/=$/, '').to_sym if meth =~ /=$/
  
  unless @methods.include?(meth)
    @methods << meth
    
    meta_def(meth) do |*values, &blk|
      block_given, values_given = !blk.nil?, !values.empty?
      @data ||= {}
      
      if !block_given && !values_given
        @data[meth] = Outline.new(parent: self) unless @data.has_key?(meth)
        
        @data[meth]
      elsif block_given && values_given
        data = values.delete_at(-1) if values.last.respond_to?(:to_hash) || values.last.respond_to?(:to_h)
        data = { value: values.length == 1 ? values.first : values }.merge!(data || {})
        
        @data[meth] = Outline.new(parent: self, data: data, &blk)
      elsif !block_given && values_given
        data = values.delete_at(-1) if values.last.respond_to?(:to_hash) || values.last.respond_to?(:to_h)
        
        if data.nil?
          @data[meth] = values.length == 1 ? values.first : values
        else
          data = { value: values.length == 1 ? values.first : values }.merge!(data || {}) unless values.empty?
          
          @data[meth] = Outline.new(parent: self, data: data)
        end
      elsif block_given && !values_given
        @data[meth] = Outline.new(parent: self, &blk)
      end
    end
    
    meta_def("#{meth}=") { |value| __send__(meth, value) }
  end
  
  __send__(meth, *args, &blk)
end

Instance Attribute Details

#dataObject (readonly)

Returns the value of attribute data.



30
31
32
# File 'lib/outline.rb', line 30

def data
  @data
end

#parentObject (readonly)

Returns the value of attribute parent.



30
31
32
# File 'lib/outline.rb', line 30

def parent
  @parent
end

Instance Method Details

#to_hObject



86
87
88
89
90
91
# File 'lib/outline.rb', line 86

def to_h
  @data ||= {}
  @data.each_with_object({}) do |(key, value), memo|
    memo[key] = value.respond_to?(:to_h) ? value.to_h : value
  end
end