rdoba 0.0.3 → 0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore ADDED
@@ -0,0 +1,43 @@
1
+ # rcov generated
2
+ coverage
3
+
4
+ # rdoc generated
5
+ rdoc
6
+
7
+ # yard generated
8
+ doc
9
+ .yardoc
10
+
11
+ # bundler
12
+ .bundle
13
+
14
+ # jeweler generated
15
+ pkg
16
+
17
+ # Have editor/IDE/OS specific files you need to ignore? Consider using a global gitignore:
18
+ #
19
+ # * Create a file at ~/.gitignore
20
+ # * Include files you want ignored
21
+ # * Run: git config --global core.excludesfile ~/.gitignore
22
+ #
23
+ # After doing this, these files will be ignored in all your git projects,
24
+ # saving you from having to 'pollute' every project you touch with them
25
+ #
26
+ # Not sure what to needs to be ignored for particular editors/OSes? Here's some ideas to get you started. (Remember, remove the leading # of the line)
27
+ #
28
+ # For MacOS:
29
+ #
30
+ #.DS_Store
31
+ #
32
+ # For TextMate
33
+ #*.tmproj
34
+ #tmtags
35
+ #
36
+ # For emacs:
37
+ #*~
38
+ #\#*
39
+ #.\#*
40
+ #
41
+ # For vim:
42
+ #*.swp
43
+ Gemfile.lock
data/CHANGES.md ADDED
@@ -0,0 +1,28 @@
1
+ Changes in rdoba
2
+ ====================
3
+
4
+ Changes in rdoba releases are listed here.
5
+
6
+ v0.0.1
7
+ ------
8
+ - Common rdoba release functions
9
+
10
+ v0.1
11
+ ------
12
+ - Common rdoba release functions. The modules are:
13
+ * common
14
+ * a
15
+ * combinations
16
+ * debug
17
+ * dup
18
+ * hashorder
19
+ * numeric
20
+ * require
21
+ * roman
22
+ * chr
23
+ * deploy
24
+ * fenc
25
+ * io
26
+ * re
27
+ * strings
28
+ * yaml
data/Gemfile CHANGED
@@ -1,13 +1,4 @@
1
1
  source "http://rubygems.org"
2
- # Add dependencies required to use your gem here.
3
- # Example:
4
- # gem "activesupport", ">= 2.3.5"
5
2
 
6
- # Add dependencies to develop your gem here.
7
- # Include everything needed to run rake, tests, features, etc.
8
- group :development do
9
- gem "shoulda", ">= 0"
10
- gem "bundler", "~> 1.0.0"
11
- gem "jeweler", "~> 1.5.2"
12
- gem "rcov", ">= 0"
13
- end
3
+ # Specify your gem's dependencies in rdoba.gemspec
4
+ gemspec
File without changes
data/README.md ADDED
@@ -0,0 +1,410 @@
1
+ # Rdoba
2
+
3
+ Rdoba, сирѣчь руби-добавокъ, есть библиотека, расширитяющая основныя классы Ruby такія какъ: Объектъ(Object), Ядро(Kernel), Строка(String), Словарь(Hash), Наборъ(Array), Пущь(NilClass) и т.д. Включаетъ модули и такія функціи:
4
+ * common - нѣкоторыя простыя методы къ Объекту, Ядру, Пущю, Набору, Строкѣ и Словрю;
5
+ * a - чтеніе и запись значеній въ Наборъ и Словарь по индексу;
6
+ * combinations - перечисленіе значеній Набора въ различномъ порядкѣ;
7
+ * debug - функціи отладки приложенія;
8
+ * dup - функціи удвоенія Словаря и Набораъ, включая ихъ вложенія;
9
+ * hashorder - перечисленіе значеній Словаря въ заданномъ порядкѣ;
10
+ * numeric - разширенный переводъ числа въ строку и строки въ число;
11
+ * require - вложенная загрузка файловъ функціею require;
12
+ * roman - переводъ римскаго числа въ строку и строки въ римское число;
13
+ * deploy - развёртка YAML-шаблоновъ;
14
+ * fenc - исправленіе кодировки въ Строкахъ (будетъ удалено по исправленіи въ ruby);
15
+ * io - функціи sscanf и sprintf съ дополнительными свойствами;
16
+ * re - простое преобразованіе Строки въ Правило;
17
+ * strings - разширеніе нѣкоторыхъ функцій Строки кириллическими правилами;
18
+ * yaml - упрощённая функція перевода Словаря или Набора въ YAML-документъ.
19
+
20
+ ## Использованіе
21
+
22
+ ### Общія методы
23
+
24
+ Добавляетъ нѣкоторыя простыя методы къ Объекту, Ядру, Пущю, Набору, Строкѣ и Словрю;
25
+
26
+ require 'rdoba/common'
27
+
28
+ ### Чтеніе и запись по индексу
29
+
30
+ Функціи позволяютъ читать и писать значенія въ Наборъ и Словарь по заданному въ видѣ Набора значеній индексу.
31
+
32
+ require 'rdoba/a'
33
+
34
+ h = { "ключъ 1" => [ 'знч', 'знч2' ],
35
+ "ключъ 2" => { "ключъ 3" => "знч3" } }
36
+
37
+ h.geta( [ "ключъ 2", "ключъ 3" ] ) # => "знч3"
38
+
39
+ h.geta( [ "ключъ 1", 0 ] ) # => "знч"
40
+
41
+ h.seta( [ "ключъ 2", "ключъ 3" ], 'НОВОЕ' ) # => "НОВОЕ"
42
+
43
+ h # => {"ключъ 1"=>["знч", "знч2"], "ключъ 2"=>{"ключъ 3"=>"НОВОЕ"}}
44
+
45
+ ### Перечисленіе значеній Набора
46
+
47
+ Перечисляетъ значенія Набора въ различныхъ ихъ кучныхъ комбинаціяхъ въ количествѣ 2^(Ѯ-1), гдѣ Ѯ - длина Набора. Существуетъ возможность прямаго или обратнаго перечичленія.
48
+
49
+ require 'rdoba/combinations'
50
+
51
+ a = [ 1,2,3 ]
52
+ a.each_comby do |x|
53
+ puts x.inspect
54
+ end
55
+
56
+ # получаемъ:
57
+ # [[1], [2], [3]]
58
+ # [[1], [2, 3]]
59
+ # [[1, 2], [3]]
60
+ # [[1, 2, 3]]
61
+
62
+ a.each_comby(:backward) do |x|
63
+ puts x.inspect
64
+ end
65
+
66
+ # получаемъ:
67
+ # [[1, 2, 3]]
68
+ # [[1, 2], [3]]
69
+ # [[1], [2, 3]]
70
+ # [[1], [2], [3]]
71
+
72
+
73
+ ### Отладка приложенія
74
+
75
+ Оладочныя функціи позволяютъ для выбранного класса выполнять заданныя куски кода или выводить на терминалъ опредѣлённый текстъ въ зависимости отъ уровня отладки.
76
+
77
+ require 'rdoba/debug'
78
+
79
+ class A
80
+ def initialize
81
+ dbp11 "Low-level initialize debug"
82
+ end
83
+
84
+ def method
85
+ @k = 0
86
+ dbp22 "Upper-level method debug"
87
+ dbg21 "@k = 1"
88
+ @k
89
+ end
90
+ end
91
+
92
+ $debug_A = 0x11
93
+
94
+ a = A.new
95
+ # выводъ
96
+ # Low-level initialize debug
97
+
98
+ a.method # => 0
99
+
100
+ a.debug = 0x21
101
+ a.method # => 1
102
+
103
+ a.debug = 0x33
104
+ a.method # => 1
105
+ # выводъ
106
+ # Upper-level method debug
107
+
108
+ ### Одвоеніе Словаря и Набора
109
+
110
+ Позволяетъ выполнять какъ обычное, такъ и вложенное одвоеніе Словаря или Набора.
111
+
112
+ require 'rdoba/dup'
113
+
114
+ a = [ 'aaa', 'bbb' ]
115
+
116
+ # выполняемъ обычное одвоеніе
117
+ b = a.dup
118
+ a[0].replace 'ccc'
119
+ a # => ["ccc", "bbb"]
120
+ b # => ["ccc", "bbb"]
121
+
122
+ # выполняемъ вложенное одвоеніе
123
+ c = a.dup(:recursive)
124
+ a[0].replace 'ddd'
125
+ a # => ["ddd", "bbb"]
126
+ c # => ["ccc", "bbb"]
127
+
128
+ ### Перечисленіе значеній Словаря въ заданномъ порядкѣ
129
+
130
+ Позволядетъ перебрать всѣ ключи и значенія Словаря по опредѣлённому порядку. Порядок сей задаётся свойствомъ Словаря :order. Если въ заданном порядкѣ не всѣ ключи опредѣлены, то сначала перебираются заданныя ключ, а затѣмъ уже остальныя въ порядкѣ какъ они заданы въ Словарѣ. Перебирать можно ключи, пары или значенія по ключамъ. 4 метода суть перебора: each, each_pair, each_key, each_value. Удаляется порядокъ методом disorder.
131
+
132
+ require 'rdoba/hashorder'
133
+
134
+ h = { "ключъ 1" => [ 'знч', 'знч2' ],
135
+ "ключъ 2" => { },
136
+ "ключъ 3" => "знч3" }
137
+
138
+ # простой переборъ паръ
139
+ h.each do |x,y|
140
+ puts x
141
+ end
142
+ # выводъ
143
+ # ключъ 1
144
+ # ключъ 2
145
+ # ключъ 3
146
+
147
+ # переборъ паръ
148
+ h.order = ['ключъ 2','ключъ 3','ключъ 1']
149
+ h.each_pair do |x,y|
150
+ puts x
151
+ end
152
+ # выводъ
153
+ # ключъ 2
154
+ # ключъ 3
155
+ # ключъ 1
156
+
157
+ # переборъ ключей
158
+ h.order = ['ключъ 2']
159
+ h.each_key do |x|
160
+ puts x
161
+ end
162
+ # выводъ
163
+ # ключъ 2
164
+ # ключъ 1
165
+ # ключъ 3
166
+
167
+ # переборъ значеній къ уже упорядоченнымъ ключамъ
168
+ h.order = ['ключъ 2','ключъ 3','ключъ 1']
169
+ h.each_value do |x|
170
+ puts x.inspect
171
+ end
172
+ # выводъ
173
+ # {}
174
+ # "знч3"
175
+ # ["знч", "знч2"]
176
+
177
+ # удаленіе порядка
178
+ h.disorder
179
+
180
+ ### Разширенный переводъ чиселъ
181
+
182
+ Добавка позволяетъ преобразовывать:
183
+ * Строку въ Число по заданному основанію, а также задавать порядокъ слѣдованія цифръ;
184
+ * Число въ Строку, задавая основаніе, заполненіе нулями Строки до опредѣлённой ширины и обрамленіе числа въ строкѣ;
185
+ * Число въ потокъ данныхъ въ видѣ Строки.
186
+
187
+ require 'rdoba/numeric'
188
+
189
+ # Строка -> Число
190
+ '1010'.to_i(2) # => 10
191
+ '0xFE'.to_i(16) # => 254
192
+
193
+ # Big-endian число
194
+ '-123'.to_i(8, :be) # => -209 (-0321)
195
+
196
+ # Число -> Строка
197
+ 1020.to_s(16, { :padding => 10 }, :style_formatting) # => "0x00000003FC"
198
+
199
+ # Число -> данныя въ Строкѣ
200
+ 1020.to_p(16, { :padding => 5 }, :be) # => "\x00\x00\x00\x03\xFC"
201
+ 1020.to_p(16, { :padding => 5 }) # => "\xFC\x03\x00\x00\x00"
202
+
203
+ ### Вложенная загрузка модулей
204
+
205
+ Добавка позволяетъ загружать ruby-файлъ съ подпапками.
206
+
207
+ require 'rdoba/require'
208
+
209
+ # есть у васъ файловая структура:
210
+ # x.rb
211
+ # x/y.rb
212
+ # x/z.rb
213
+ # можно загрузить её разомъ такъ:
214
+ require 'x', :recursive
215
+
216
+ ### Обработка римскихъ чиселъ
217
+
218
+ Добавка позволяетъ преобразовывать римскія числа въ Строку и изъ неё.
219
+
220
+ require 'rdoba/roman'
221
+
222
+ 'XVI'.rom # => 16
223
+
224
+ 144.to_rom # => "CXLIV"
225
+
226
+ ### Развёртка YAML-шаблоновъ
227
+
228
+ require 'rdoba/deploy'
229
+
230
+ ### Исправленіе кодировки въ Строкахъ
231
+
232
+ Исправляетъ кодировку Строки въ ruby 1.9 въ Encoding.default_internal. Если оно не задано, то въ 'UTF-8'. Часто такой финтъ нуженъ для въставленія совместимости забугорныхъ приложеній и кириллицы.
233
+
234
+ !!! будетъ удалено по исправленіи въ ruby
235
+
236
+ require 'rdoba/fenc'
237
+
238
+ s = 'eee'
239
+ s.encoding # => #<Encoding:US/ASCII>
240
+
241
+ s.fenc
242
+ s.encoding # => #<Encoding:UTF-8>
243
+
244
+ ### Новыя функціи sscanf, sprintf и consolize
245
+
246
+ Въ функциію sprintf добавленъ ключъ 'P', позволяющій сохранить просто данныя чего-либо (въ частности Числа) въ строку. Функціи 'scanf' и 'consolize' у Строки позволяютъ разбирать строку согласно переданнымъ въ scanf ключамъ и прощать строку, убирая лишние знаки \r, соотвѣтственно.
247
+
248
+ #### sprintf
249
+
250
+ Форматъ ключа 'P' функціи sprintf: %сдвигъ.заполненіе+P
251
+ * сдвигъ есть сдвигъ новой строки от начала въ пробѣлахъ;
252
+ * заполненіе есть дополненіе преобразованного въ Строку Числа нулями;
253
+ * + сообщаетъ о томъ, что Число нужно выразить въ big-endian.
254
+
255
+ require 'rdoba/io'
256
+
257
+ sprintf "%5P", 1000 # => " \xE8\x03"
258
+ sprintf "%.5P", 1000 # => "\xE8\x03\x00\x00\x00"
259
+
260
+ sprintf "%5.10+P", 1000 # => " \x00\x00\x00\x00\x00\x00\x00\x00\x03\xE8"
261
+
262
+ #### scanf
263
+
264
+ Позволяетъ преобразовать согласно заданной строкѣ ключей. Ключи здѣ такія же какъ в Kernel::sprintf.
265
+
266
+ s = 'значеніе = 1000'
267
+ s.scanf "%s = %i" # => [["значеніе", 1000]]
268
+
269
+ #### consolize
270
+
271
+ Функція упрощаетъ содержимое строки, как бы при выводѣ её на консоль.
272
+
273
+ s = "string\rval"
274
+ s.consolize # => "valing"
275
+
276
+ ### Преобразованіе Строки въ Правило
277
+
278
+ require 'rdoba/re'
279
+
280
+ a = 'строка.'
281
+ b = 'доп.строка.доп'
282
+ a.to_res # => "строка\\."
283
+ a.to_re # => /строка\./i
284
+
285
+ b.match a.to_re # => #<MatchData "строка.">
286
+
287
+ ### Расширеніе строки
288
+
289
+ Здѣ суть опредѣлены функціи, разширяющія возможности Строки кириллическими правилами, а также дополняющія Строку новыми возможностями.
290
+
291
+ require 'rdoba/strings'
292
+
293
+ #### Новыя методы класса
294
+
295
+ ##### upcase
296
+
297
+ Переводъ знака въ верхнее значеніе:
298
+
299
+ a = 'ц'
300
+ String.upcase(a) # => "Ц"
301
+ a = 0x401 # 'ё'
302
+ String.upcase(a) # => "Ё"
303
+
304
+ ##### downcase
305
+
306
+ Переводъ знака въ нижнее значеніе:
307
+
308
+ a = 'Ц'
309
+ String.downcase(a) # => "ц"
310
+ a = 0x400 # 'Ё'
311
+ String.downcase(a) # => "ё"
312
+
313
+
314
+ #### Новыя методы экземпляра
315
+
316
+ ##### upcase
317
+
318
+ Переводъ строки въ верхнее значеніе. Функція можетъ принимать дополнительное значеніе 'FirstChar', которое принуждаетъ переводить не всю строку, а только первый знакъ.
319
+
320
+ a = 'строка'
321
+ a.upcase # => "СТРОКА"
322
+ a = 'строка'
323
+ a.upcase(String::FirstChar) # => "Строка"
324
+
325
+ ##### downcase
326
+
327
+ Переводъ знака въ нижнее значеніе. Функція можетъ принимать дополнительное значеніе 'FirstChar', которое принуждаетъ пе
328
+ реводить не всю строку, а только первый знакъ.
329
+
330
+ a = 'СТРОКА'
331
+ a.downcase # => "строка"
332
+ a = 'СТРОКА'
333
+ a.downcase(String::FirstChar) # => "сТРОКА"
334
+
335
+ ##### reverse
336
+
337
+ Обращаетъ строку. Допускается проводить обращеніе съ перемѣннымъ шагомъ, а также побайтно.
338
+
339
+ a = 'строка'
340
+
341
+ # обычное обращеніе
342
+ a.reverse # => "акортс"
343
+
344
+ # побайтное обращеніе
345
+ a.reverse(String::ByteByByte) # =>"\xB0\xD0\xBA\xD0\xBE\xD0\x80\xD1\x82\xD1\x81\xD1"
346
+
347
+ # обращеніе съ шагомъ 2
348
+ a.reverse(2) # => "карост"
349
+
350
+ ##### compare_to
351
+
352
+ Работаетъ такъ же какъ и '<=>', но можетъ принимать дополнительное значеніе ignore_diacritics, которое вынуждаетъ методъ проводить сравненіе отбрасывая надстрочники:
353
+
354
+ a = 'а҆́гнецъ'
355
+ b = 'а҆гкѵ́ра'
356
+
357
+ a <=> b # => -1
358
+ a.compare_to(b) # => -1
359
+ a.compare_to(b, :ignore_diacritics) # => 1
360
+ a.compare_to(b, :ignore_diacritics => true) # => 1
361
+
362
+ #### Новыя методы для Fixnum
363
+ ##### chr
364
+
365
+ Возвращаетъ знакъ изъ числа, возпринимая его какъ кодъ.
366
+
367
+ 1094.chr # => "ц"
368
+
369
+ #### Новыя методы для ruby 1.8
370
+ ##### ord
371
+
372
+ Возвращаетъ числовой кодъ перваго знака строки:
373
+
374
+ a = 'ёжъ'
375
+ a.ord # => 1025 (0x401)
376
+
377
+ ### Упрощённый переводъ въ YAML
378
+
379
+ Позволяетъ простенько перевести экземпляры классовъ Словаря, Набора, Строки и Числа въ YAML-документъ. Также возможно указать порядокъ выведенія ключей въ Словарѣ.
380
+
381
+ h = { "ключъ 1" => [ 'знч', 'знч2' ],
382
+ "ключъ 2" => 10 }
383
+
384
+ puts h.to_yml
385
+ ---
386
+ ключъ 2: 10
387
+ ключъ 1:
388
+ - знч
389
+ - знч2
390
+
391
+ puts h.to_yml(:order => ["ключъ 1", "ключъ 2"])
392
+ ---
393
+ ключъ 1:
394
+ - знч
395
+ - знч2
396
+ ключъ 2: 10
397
+
398
+
399
+ puts h.to_yml(:order => ["ключъ 2", "ключъ 1"])
400
+ ---
401
+ ключъ 2: 10
402
+ ключъ 1:
403
+ - знч
404
+ - знч2
405
+
406
+ # Права
407
+
408
+ Авторскія и исключительныя права (а) 2011 Малъ Скрылевъ
409
+ Зри LICENSE за подробностями.
410
+
data/Rakefile CHANGED
@@ -1,53 +1,3 @@
1
1
  require 'rubygems'
2
2
  require 'bundler'
3
- begin
4
- Bundler.setup(:default, :development)
5
- rescue Bundler::BundlerError => e
6
- $stderr.puts e.message
7
- $stderr.puts "Run `bundle install` to install missing gems"
8
- exit e.status_code
9
- end
10
- require 'rake'
11
-
12
- require 'jeweler'
13
- Jeweler::Tasks.new do |gem|
14
- # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
15
- gem.name = "rdoba"
16
- gem.homepage = "http://github.com/3aHyga/rdoba"
17
- gem.license = "MIT"
18
- gem.summary = %Q{Ruby additionals}
19
- gem.description = %Q{Ruby extransion library. It extends Kernel, Object and some other classes}
20
- gem.email = "3aHyga@gmail.com"
21
- gem.authors = ["Malo Skrylevo"]
22
- # Include your dependencies below. Runtime dependencies are required when using your gem,
23
- # and development dependencies are only needed for development (ie running rake tasks, tests, etc)
24
- # gem.add_runtime_dependency 'jabber4r', '> 0.1'
25
- # gem.add_development_dependency 'rspec', '> 1.2.3'
26
- end
27
- Jeweler::RubygemsDotOrgTasks.new
28
-
29
- require 'rake/testtask'
30
- Rake::TestTask.new(:test) do |test|
31
- test.libs << 'lib' << 'test'
32
- test.pattern = 'test/**/test_*.rb'
33
- test.verbose = true
34
- end
35
-
36
- require 'rcov/rcovtask'
37
- Rcov::RcovTask.new do |test|
38
- test.libs << 'test'
39
- test.pattern = 'test/**/test_*.rb'
40
- test.verbose = true
41
- end
42
-
43
- task :default => :test
44
-
45
- require 'rake/rdoctask'
46
- Rake::RDocTask.new do |rdoc|
47
- version = File.exist?('VERSION') ? File.read('VERSION') : ""
48
-
49
- rdoc.rdoc_dir = 'rdoc'
50
- rdoc.title = "rdoba #{version}"
51
- rdoc.rdoc_files.include('README*')
52
- rdoc.rdoc_files.include('lib/**/*.rb')
53
- end
3
+ Bundler::GemHelper.install_tasks
data/lib/rdoba/a.rb ADDED
@@ -0,0 +1,114 @@
1
+ #!/usr/bin/ruby -KU
2
+ #<Encoding:UTF-8>
3
+
4
+ require 'rdoba/debug'
5
+
6
+ class Array
7
+ def geta(index, options = {}) #TODO => [] + class Index
8
+ dbp11 "[geta] <<< array = #{self.inspect}, index = #{index.inspect}, options = #{options.inspect}"
9
+ options[:сокр] ||= @сокр
10
+
11
+ if index.class == Array
12
+ return self if index == [] or index == ['']
13
+ index = index.clone
14
+ value = self[index.shift]
15
+ (value.class == Hash or value.class == Array) ? value.geta(index, options) : value
16
+ else
17
+ geta_value(index, options)
18
+ end
19
+ end
20
+
21
+ end
22
+
23
+
24
+ class Hash
25
+
26
+ protected
27
+
28
+ def geta_value(cid, options = {})
29
+ res = ((not cid) || cid.empty?) && self || self[cid] ||
30
+ (options[:сокр] && (self[options[:сокр][cid]] || self[options[:сокр].reverse[cid]]))
31
+
32
+ if not res and options[:try_regexp]
33
+ self.keys.each do |key|
34
+ break res = self[key] if key.rmatch(cid)
35
+ if options[:сокр]
36
+ options[:сокр].each_pair do |val1, val2|
37
+ break res = self[key] if key.rmatch(cid.gsub(/#{val1}/, val2)) or
38
+ key.rmatch(cid.gsub(/#{val2}/, val1))
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ res
45
+ end
46
+
47
+ public
48
+
49
+ def geta(index, options = {}) #TODO => [] + class Index
50
+ dbp11 "[geta] <<< hash = #{self.inspect}, index = #{index.inspect}, options = #{options.inspect}"
51
+ options[:сокр] ||= @сокр
52
+
53
+ if index.class == Array
54
+ return self if index == [] or index == ['']
55
+ index = index.clone
56
+ value = geta_value(index.shift, options)
57
+ (value.class == Hash or value.class == Array) ? value.geta(index, options) : value
58
+ else
59
+ geta_value(index, options)
60
+ end
61
+ end
62
+
63
+ def seta(index, value, options = {}) #TODO => [] + class Index
64
+ dbp11 "[seta] <<< index: #{index.inspect}, value: #{value.inspect}, options: #{options.inspect}"
65
+ options[:сокр] ||= @сокр
66
+
67
+ return self[index] = value if index.class != Array # TODO spec index
68
+
69
+ back = 0
70
+ index = index.reverse.map do |x|
71
+ if x.empty?
72
+ back += 1
73
+ nil
74
+ elsif back > 0
75
+ back -= 1
76
+ nil
77
+ else
78
+ x
79
+ end
80
+ end.compact.reverse
81
+ dbp12 "[seta]> result index: #{index.inspect}"
82
+
83
+ obj = nil
84
+ o = self
85
+ dbp14 "[seta]>> self: #{o.inspect}"
86
+ set_idx = index.pop
87
+ par_class = set_idx =~ /^\d+$/ ? Array : Hash
88
+ par_idx = nil
89
+ index.each do |idx|
90
+ unless o
91
+ dbp14 "[seta]>> parent idx: #{par_idx.inspect}, idx: #{idx.inspect}, parent obj: #{o.inspect}"
92
+ o = idx =~ /^\d+$/ && [] || {}
93
+ obj[par_idx] = o
94
+ end
95
+ obj = o
96
+ o = (obj.class == Hash) ? obj.geta_value(idx, options) : obj[idx]
97
+ dbp14 "[seta]>> cur idx: #{idx.inspect}, parent obj: #{obj.inspect}, obj: #{o.inspect}"
98
+ unless o
99
+ if idx == index.last
100
+ o = par_class.new
101
+ obj[idx] = o
102
+ else
103
+ par_idx = idx =~ /^\d+$/ && idx.to_i || idx
104
+ end
105
+ end
106
+ end
107
+
108
+ raise "Invalid path" unless o # TODO special exception
109
+
110
+ o[set_idx] = value
111
+ end
112
+
113
+ end
114
+