rdoba 0.0.3 → 0.1

Sign up to get free protection for your applications and to get access to all the features.
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
+