Class: Posifile

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

Constant Summary collapse

INVALID_CHARS =
" !@#$\%*()-\&\'\"<>.,;:[]{}\'\`^+\\/"
@@specifications =
{}
@@conditions =
{}
@@attr_names =
{}
@@pos_attr =
{}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(data_file_name_or_text) ⇒ Posifile

Returns a new instance of Posifile.



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/posifile.rb', line 13

def initialize(data_file_name_or_text)
  if data_file_name_or_text.class == String
    @data_file = data_file_name_or_text
  elsif data_file_name_or_text .class == Hash
    @file_content = [data_file_name_or_text[:text]]
  else
    raise InvalidPositionFileFormat, "Pass a file path or text."
  end

  check_specification_hash
  file_content.each do |line|
    if file_content.length == 1
      build_attributes_from_hash(@@specifications[class_name][0], line, nil)
    else
      specification_index(line) do |line_, index|
        build_attributes_from_hash(@@specifications[class_name][index], line_, @@attr_names[class_name][index])
      end
    end
  end
end

Instance Attribute Details

#data_fileObject

Returns the value of attribute data_file.



11
12
13
# File 'lib/posifile.rb', line 11

def data_file
  @data_file
end

#raw_contentObject

Returns the value of attribute raw_content.



11
12
13
# File 'lib/posifile.rb', line 11

def raw_content
  @raw_content
end

Class Method Details

.class_nameObject



134
135
136
137
138
139
140
141
# File 'lib/posifile.rb', line 134

def self.class_name
  name = self
  while name.superclass != Posifile
    name = name.superclass
  end

  name
end

.gap_in_specification?(spec_array) ⇒ Boolean

Returns:

  • (Boolean)


104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/posifile.rb', line 104

def self.gap_in_specification?(spec_array)
  num_ar = []
  spec_array.each_with_index do |spec, index|
    spec.each_value do |range|
      range.each do |item|
        num_ar[index] ||= []
        num_ar[index][item] ||= 0
        num_ar[index][item] += 1
      end
    end
  end
  valid = false
  num_ar.each do |array|
    if array.include? nil
      valid = true
    end
  end
  valid
end

.higherObject



124
125
126
127
128
129
130
131
132
# File 'lib/posifile.rb', line 124

def self.higher
  higher_number = 0
  @@specifications[class_name][0].each_value do |range|
    if range.max > higher_number
        higher_number = range.max
    end
  end
  higher_number
end

.lines_where(range, value, &block) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/posifile.rb', line 43

def self.lines_where(range,value, &block)
  @@attr_names[class_name] ||= []
  length_before = @@attr_names[class_name].length
  @@conditions[class_name] ||= []
  @@conditions[class_name] << { range => value }
  yield
  length_after = @@attr_names[class_name].length
  if length_before == length_after
    @@attr_names[class_name] << nil
  end
  section_code_hash = { "section_code" => range }
  if @@specifications[class_name]
    @@specifications[class_name].last.merge!(section_code_hash)
  end
end

.overlap_in_specification?(spec_array) ⇒ Boolean

Returns:

  • (Boolean)


84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/posifile.rb', line 84

def self.overlap_in_specification?(spec_array)
  num_ar = []
  spec_array.each_with_index do |spec, index|
    spec.each_value do |range|
      range.each do |item|
        num_ar[index] ||= []
        num_ar[index][item] ||= 0
        num_ar[index][item] += 1
      end
    end
  end
  valid = false
  num_ar.each do |array|
    if array.include?(2)
      valid = true
    end
  end
  valid
end

.set_attr_name(attr_name) ⇒ Object



59
60
61
62
# File 'lib/posifile.rb', line 59

def self.set_attr_name(attr_name)
  @@attr_names[class_name] ||= []
  @@attr_names[class_name] << attr_name
end

.set_specification(hash) ⇒ Object



34
35
36
37
38
39
40
41
# File 'lib/posifile.rb', line 34

def self.set_specification(hash)
  if valid_names?(hash)
    @@specifications[class_name] ||= []
    @@specifications[class_name] << hash
  else
    raise InvalidFieldName, "Fields names contain invalid characteres for method names."
  end
end

.valid_names?(hash) ⇒ Boolean

Returns:

  • (Boolean)


64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/posifile.rb', line 64

def self.valid_names?(hash)
  check = true
  hash.each_key do |key|
    key.split('').each do |letter|
      unless letter.downcase == letter
        check = false
      end
      if INVALID_CHARS.split("").include?(letter)
        check = false
      end
    end
  end

  check
end

.valid_specification?Boolean

Returns:

  • (Boolean)


80
81
82
# File 'lib/posifile.rb', line 80

def self.valid_specification?
  not gap_in_specification?(@@specifications[class_name]) || overlap_in_specification?(@@specifications[class_name])
end

Instance Method Details

#add_method_to_pos_attr(field) ⇒ Object



207
208
209
210
211
212
# File 'lib/posifile.rb', line 207

def add_method_to_pos_attr(field)
  @@pos_attr[class_name] ||= []
  unless @@pos_attr[class_name].include? field
    @@pos_attr[class_name] << field
  end
end

#build_attributes_from_hash(specification_hash, line, attr_name) ⇒ Object



224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
# File 'lib/posifile.rb', line 224

def build_attributes_from_hash(specification_hash, line, attr_name)
  if attr_name
    values_hash = {}
    specification_hash.keys.map do |key|
      values_hash[key] = field_value(key, specification_hash, line )
    end

    method_name = change_name(field_value(attr_name, specification_hash, line))

    add_method_to_pos_attr(method_name)
    self.instance_eval "
      def #{method_name}\n
        #{values_hash.inspect}\n
      end
    "
  else
    specification_hash.each_key do |key|
      add_method_to_pos_attr(key)
      self.instance_eval "
        def #{key}
          \"#{field_value(key, specification_hash, line)}\"
        end
      "
    end
  end
end

#change_name(original) ⇒ Object

Once the name is gonna be used as method name, this changes the name when it contains invalid characters.



216
217
218
219
220
221
222
# File 'lib/posifile.rb', line 216

def change_name(original)
  original.gsub!(' ','_')
  INVALID_CHARS.split('').each do |char|
    original.gsub!(char,'')
  end
  original.downcase
end

#check_condition(condition_hash, line) ⇒ Object

Checks if a given line matches the line_where condition declare in the class



171
172
173
# File 'lib/posifile.rb', line 171

def check_condition(condition_hash, line)
  line[condition_hash.keys.first] == condition_hash.values.first
end

#check_specification_hashObject



152
153
154
155
156
# File 'lib/posifile.rb', line 152

def check_specification_hash
  if @@specifications[class_name].nil?
    raise FieldsNotSpecified, "You should call set_specifications in you model, so we can build the object with the corresponding attribuites. Check documentation on how to do so."
  end
end

#class_nameObject



143
144
145
146
147
148
149
150
# File 'lib/posifile.rb', line 143

def class_name
  name = self.class
  while name.superclass != Posifile
    name = name.superclass
  end

  name
end

#field_value(field_name, specification_hash, line) ⇒ Object

Get the value of a specifc position declared in the specification hash



188
189
190
191
192
193
194
195
196
197
198
199
200
201
# File 'lib/posifile.rb', line 188

def field_value(field_name, specification_hash, line)
  field_name = field_name.to_s
  content_ar = line.split('')
  value_str = ''
  if !specification_hash.keys.include? field_name 
    raise InvalidAttrName, "The specified attr name was not found in the specification hash."
  else
    range = specification_hash[field_name]
    range.each do |n|
      value_str.concat content_ar[n]
    end
    value_str.strip
  end
end

#file_contentObject



175
176
177
178
179
180
181
182
183
184
185
# File 'lib/posifile.rb', line 175

def file_content
  if @data_file
    if raw_content.nil?
      file = File.open(@data_file, "r")
      @raw_content = file.readlines
    end
    return @raw_content
  else
    @file_content
  end
end

#pos_attributesObject



203
204
205
# File 'lib/posifile.rb', line 203

def pos_attributes
  @@pos_attr[class_name]
end

#specification_index(line) ⇒ Object



158
159
160
161
162
163
164
165
166
167
168
# File 'lib/posifile.rb', line 158

def specification_index(line)
  i = 0
  if @@conditions[class_name]
    @@conditions[class_name].each_with_index do |hash, num|
      if check_condition(hash,line)
        yield line, num
      end
    end
  end
  i
end