Class: RubyToBlock::Block::Base

Inherits:
Object
  • Object
show all
Defined in:
app/models/concerns/ruby_to_block/block/base.rb

Overview

すべてのブロックのベースクラス

Constant Summary collapse

STRING_RE =
'\s*("[^"]*"|\'[^\']*\')\s*'

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Base



138
139
140
141
142
143
144
145
146
147
148
# File 'app/models/concerns/ruby_to_block/block/base.rb', line 138

def initialize(options = {})
  @fields = options[:fields] || {}
  @values = options[:values] || {}
  @statements = options[:statements] || {}

  if @statements.length > 0
    @statements.values.each do |s|
      s.parent = self
    end
  end
end

Instance Attribute Details

#fieldsObject

Returns the value of attribute fields.



12
13
14
# File 'app/models/concerns/ruby_to_block/block/base.rb', line 12

def fields
  @fields
end

#parentObject

Returns the value of attribute parent.



9
10
11
# File 'app/models/concerns/ruby_to_block/block/base.rb', line 9

def parent
  @parent
end

#prev_siblingObject

Returns the value of attribute prev_sibling.



10
11
12
# File 'app/models/concerns/ruby_to_block/block/base.rb', line 10

def prev_sibling
  @prev_sibling
end

#siblingObject

Returns the value of attribute sibling.



11
12
13
# File 'app/models/concerns/ruby_to_block/block/base.rb', line 11

def sibling
  @sibling
end

#statementsObject

Returns the value of attribute statements.



14
15
16
# File 'app/models/concerns/ruby_to_block/block/base.rb', line 14

def statements
  @statements
end

#valuesObject

Returns the value of attribute values.



13
14
15
# File 'app/models/concerns/ruby_to_block/block/base.rb', line 13

def values
  @values
end

Class Method Details

.blocknize(regexp, options = {}) ⇒ Object



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
# File 'app/models/concerns/ruby_to_block/block/base.rb', line 20

def self.blocknize(regexp, options = {})
  klass = (class << self; self; end)
  klass.instance_eval do
    define_method(:regexp_string) do
      regexp
    end

    %w(
      statement
      value
      indent
      inline
      priority
    ).each do |name|
      sym = name.to_sym
      if options.key?(sym)
        v = options[sym]
        if v.is_a?(TrueClass) || v.is_a?(FalseClass)
          sym = "#{name}?".to_sym
        end
        define_method(sym) do
          v
        end
      end
    end
  end
end

.indent?Boolean

インデントする必要があるかどうかを返す



77
78
79
# File 'app/models/concerns/ruby_to_block/block/base.rb', line 77

def self.indent?
  false
end

.inherited(child) ⇒ Object



16
17
18
# File 'app/models/concerns/ruby_to_block/block/base.rb', line 16

def self.inherited(child)
  Block.register(child)
end

.inline?Boolean

インラインのブロックかどうかを返す



82
83
84
# File 'app/models/concerns/ruby_to_block/block/base.rb', line 82

def self.inline?
  false
end

.priorityObject

正規表現の優先度を返す



72
73
74
# File 'app/models/concerns/ruby_to_block/block/base.rb', line 72

def self.priority
  0
end

.process_else(context) ⇒ true, false

elseを発見した時の処理



123
124
125
# File 'app/models/concerns/ruby_to_block/block/base.rb', line 123

def self.process_else(context)
  false
end

.process_end(context) ⇒ true, false

endを発見した時の処理



131
132
133
134
135
136
# File 'app/models/concerns/ruby_to_block/block/base.rb', line 131

def self.process_end(context)
  context.current_block = context.statement[1]
  context.statement_stack.pop

  true
end

.process_match_data(md, context) ⇒ true, false

正規表現にマッチしたデータを解析する



90
91
92
# File 'app/models/concerns/ruby_to_block/block/base.rb', line 90

def self.process_match_data(md, context)
  true
end

.process_value_string(context, block, string, name) ⇒ true, false

値を格納した文字列を解析する



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'app/models/concerns/ruby_to_block/block/base.rb', line 98

def self.process_value_string(context, block, string, name)
  # HACK: 最初と最後の括弧を取り除く
  string = string[1..-2] while string[0] == '(' && string[-1] == ')'

  value_md = Block.value_regexp.match(string)
  return false unless value_md

  _current_block = context.current_block
  context.current_block = block
  context.value_name_stack.push(name)

  unless Block.process_match_data(value_md, context)
    Block.process_match_data(value_md, context, 'ruby_expression')
  end

  context.value_name_stack.pop
  context.current_block = _current_block

  true
end

.regexpObject

正規表現を返す



53
54
55
# File 'app/models/concerns/ruby_to_block/block/base.rb', line 53

def self.regexp
  @regexp ||= Regexp.new(regexp_string)
end

.statement?Boolean

ステートメントかどうかを返す

trueの場合、Block.statement_regexpに追加される



60
61
62
# File 'app/models/concerns/ruby_to_block/block/base.rb', line 60

def self.statement?
  false
end

.typeObject



48
49
50
# File 'app/models/concerns/ruby_to_block/block/base.rb', line 48

def self.type
  name.sub('RubyToBlock::Block::', '').underscore
end

.value?Boolean

値かどうかを返す

trueの場合、Block.value_regexpに追加される



67
68
69
# File 'app/models/concerns/ruby_to_block/block/base.rb', line 67

def self.value?
  false
end

Instance Method Details

#[](name) ⇒ Object



172
173
174
# File 'app/models/concerns/ruby_to_block/block/base.rb', line 172

def [](name)
  @fields[name]
end

#add_statement(name, block) ⇒ Object



176
177
178
179
180
181
182
183
184
185
186
# File 'app/models/concerns/ruby_to_block/block/base.rb', line 176

def add_statement(name, block)
  b = @statements[name]
  if b
    b = b.sibling while b.sibling
    b.sibling = block
  else
    block.parent = self
    @statements[name] = block
  end
  self
end

#add_value(name, block) ⇒ Object



188
189
190
191
192
193
194
195
196
197
198
# File 'app/models/concerns/ruby_to_block/block/base.rb', line 188

def add_value(name, block)
  b = @values[name]
  if b
    b = b.sibling while b.sibling
    b.sibling = block
  else
    block.parent = self
    @values[name] = block
  end
  self
end

#indent_levelObject



206
207
208
209
210
211
212
213
214
# File 'app/models/concerns/ruby_to_block/block/base.rb', line 206

def indent_level
  b = self
  level = 0
  while b.parent
    b = b.parent
    level += 1 if b.class.indent?
  end
  level
end

#inline?Boolean



164
165
166
# File 'app/models/concerns/ruby_to_block/block/base.rb', line 164

def inline?
  @inline ||= self.class.inline?
end

#null?Boolean



168
169
170
# File 'app/models/concerns/ruby_to_block/block/base.rb', line 168

def null?
  false
end

#to_xml(parent) ⇒ Object



150
151
152
153
154
155
156
157
158
# File 'app/models/concerns/ruby_to_block/block/base.rb', line 150

def to_xml(parent)
  e = parent.add_element('block', 'type' => type)
  e.add_attribute('inline', 'true') if inline?
  fields_to_xml(e)
  values_to_xml(e)
  statements_to_xml(e)
  sibling_to_xml(e)
  e
end

#typeObject



160
161
162
# File 'app/models/concerns/ruby_to_block/block/base.rb', line 160

def type
  @type ||= self.class.type
end