facets 2.6.0 → 2.7.0
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/HISTORY.rdoc +331 -35
- data/MANIFEST +685 -826
- data/{doc/guide/notes.rd → NOTES} +0 -0
- data/README.rdoc +73 -25
- data/Rakefile +245 -2
- data/TODO +5 -0
- data/demo/hook.rd +47 -0
- data/demo/scenario_require.rd +9 -0
- data/doc/README.more +24 -6
- data/doc/manual/about.rb +47 -0
- data/doc/manual/annotations.rdoc +60 -0
- data/doc/manual/associations.rdoc +55 -0
- data/doc/manual/blockups.rdoc +101 -0
- data/doc/manual/capsule.rdoc +34 -0
- data/doc/manual/command.rdoc +177 -0
- data/doc/manual/core.rdoc +37 -0
- data/doc/manual/faq.rdoc +32 -0
- data/doc/manual/typecast.html +112 -0
- data/lib/core/facets.rb +359 -11
- data/lib/core/facets/array/combination.rb +3 -3
- data/lib/core/facets/array/index.rb +4 -1
- data/lib/core/facets/array/permutation.rb +2 -2
- data/lib/core/facets/array/product.rb +1 -1
- data/lib/core/facets/binding/eval.rb +1 -1
- data/lib/core/facets/denumerable.rb +76 -0
- data/lib/core/facets/duplicable.rb +34 -0
- data/lib/core/facets/enumerable/count.rb +10 -4
- data/lib/core/facets/enumerable/defer.rb +77 -0
- data/lib/core/facets/enumerable/each_by.rb +1 -1
- data/lib/core/facets/enumerable/every.rb +35 -0
- data/lib/{more/facets/elementwise.rb → core/facets/enumerable/ewise.rb} +0 -0
- data/lib/core/facets/enumerable/filter.rb +25 -0
- data/lib/core/facets/enumerable/group_by.rb +1 -1
- data/lib/core/facets/enumerable/none.rb +3 -2
- data/lib/core/facets/enumerable/one.rb +3 -2
- data/lib/core/facets/enumerable/per.rb +61 -0
- data/lib/core/facets/exception/raised.rb +14 -0
- data/lib/core/facets/integer/odd.rb +5 -1
- data/lib/core/facets/kernel/__dir__.rb +13 -3
- data/lib/core/facets/kernel/__here__.rb +14 -0
- data/lib/core/facets/kernel/__method__.rb +9 -3
- data/lib/core/facets/kernel/ask.rb +1 -0
- data/lib/core/facets/kernel/equate.rb +13 -0
- data/lib/core/facets/kernel/extension.rb +9 -0
- data/lib/core/facets/kernel/identical.rb +4 -0
- data/lib/core/facets/kernel/instance_exec.rb +2 -1
- data/lib/core/facets/kernel/method.rb +49 -0
- data/lib/core/facets/kernel/object_send.rb +2 -2
- data/lib/core/facets/kernel/{state.rb → object_state.rb} +23 -12
- data/lib/core/facets/kernel/require_all.rb +6 -1
- data/lib/core/facets/kernel/require_local.rb +8 -1
- data/lib/core/facets/kernel/require_relative.rb +52 -0
- data/lib/core/facets/kernel/source_location.rb +13 -0
- data/lib/core/facets/kernel/tap.rb +13 -6
- data/lib/core/facets/module/attr_setter.rb +57 -0
- data/lib/core/facets/module/instance_method.rb +24 -0
- data/lib/core/facets/module/module_load.rb +60 -44
- data/lib/core/facets/module/module_require.rb +1 -0
- data/lib/core/facets/nilclass/to_f.rb +1 -1
- data/lib/core/facets/objectspace/op_fetch.rb +3 -0
- data/lib/core/facets/proc/curry.rb +4 -3
- data/lib/core/facets/string/bytes.rb +10 -4
- data/lib/core/facets/string/camelcase.rb +6 -5
- data/lib/core/facets/string/chars.rb +5 -1
- data/lib/core/facets/string/each_char.rb +1 -1
- data/lib/core/facets/string/each_word.rb +1 -1
- data/lib/core/facets/string/lines.rb +11 -4
- data/lib/core/facets/string/start_with.rb +9 -2
- data/lib/core/facets/string/unfold.rb +27 -0
- data/lib/core/facets/symbol/succ.rb +3 -3
- data/lib/core/facets/symbol/thrown.rb +20 -0
- data/lib/core/facets/symbol/to_proc.rb +3 -2
- data/lib/core/facets/time/to_time.rb +1 -1
- data/lib/core/facets/to_hash.rb +41 -100
- data/lib/core/facets/unboundmethod/name.rb +20 -23
- data/lib/more/facets/ansicode.rb +1 -10
- data/lib/more/facets/autoarray.rb +3 -31
- data/lib/more/facets/basicobject.rb +73 -0
- data/lib/more/facets/blankslate.rb +2 -66
- data/lib/{lore → more}/facets/cgi.rb +0 -0
- data/lib/more/facets/class_extend.rb +1 -0
- data/lib/{lore → more}/facets/continuation.rb +0 -0
- data/lib/{lore → more}/facets/date.rb +3 -3
- data/lib/more/facets/enumargs.rb +192 -0
- data/lib/more/facets/enumerablepass.rb +2 -216
- data/lib/more/facets/enumerator.rb +62 -0
- data/lib/more/facets/{equatable.rb → equitable.rb} +11 -11
- data/lib/more/facets/expirable.rb +13 -41
- data/lib/{lore → more}/facets/fileutils.rb +0 -0
- data/lib/{lore → more}/facets/fileutils/head.rb +0 -0
- data/lib/{lore → more}/facets/fileutils/safe_ln.rb +0 -0
- data/lib/{lore → more}/facets/fileutils/slice.rb +0 -0
- data/lib/{lore → more}/facets/fileutils/tail.rb +0 -0
- data/lib/{lore → more}/facets/fileutils/wc.rb +0 -0
- data/lib/{lore → more}/facets/fileutils/whereis.rb +0 -0
- data/lib/{lore → more}/facets/fileutils/which.rb +0 -0
- data/lib/{lore → more}/facets/getoptlong.rb +0 -0
- data/lib/more/facets/hook.rb +2 -29
- data/lib/more/facets/inheritor.rb +2 -2
- data/lib/more/facets/instance_eval.rb +50 -0
- data/lib/more/facets/instance_function.rb +78 -0
- data/lib/more/facets/main.rb +20 -15
- data/lib/more/facets/memoize.rb +1 -113
- data/lib/more/facets/module/attr.rb +83 -0
- data/lib/more/facets/module/attr_tester.rb +44 -0
- data/lib/more/facets/module/attr_toggler.rb +59 -0
- data/lib/more/facets/module/attr_validator.rb +34 -0
- data/lib/more/facets/{class_extension.rb → module/class_extend.rb} +21 -13
- data/lib/more/facets/once.rb +59 -0
- data/lib/more/facets/openmodule.rb +1 -0
- data/lib/more/facets/orderedhash.rb +1 -33
- data/lib/{lore → more}/facets/ostruct.rb +0 -0
- data/lib/more/facets/ostructable.rb +1 -4
- data/lib/more/facets/partial.rb +18 -16
- data/lib/{lore → more}/facets/pathname.rb +0 -0
- data/lib/more/facets/preinitialize.rb +157 -0
- data/lib/{lore → more}/facets/rbconfig.rb +0 -0
- data/lib/more/facets/recorder.rb +1 -2
- data/lib/{lore → more}/facets/set.rb +0 -0
- data/lib/{lore → more}/facets/shellwords.rb +0 -0
- data/lib/{lore → more}/facets/uri.rb +0 -0
- data/lib/{lore → more}/facets/yaml.rb +0 -0
- data/lib/{lore → more}/facets/zlib.rb +0 -0
- data/meta/loadpath +0 -1
- data/meta/sitemap +4 -0
- data/meta/version +1 -1
- data/test/core/enumerable/test_count.rb +1 -1
- data/test/{more/test_filter.rb → core/enumerable/test_defer.rb} +24 -22
- data/test/{more/test_elementor.rb → core/enumerable/test_every.rb} +2 -15
- data/test/core/enumerable/test_ewise.rb +23 -0
- data/test/core/enumerable/test_per.rb +18 -0
- data/test/core/enumerable/test_take.rb +13 -0
- data/test/core/kernel/test_deepcopy.rb +1 -1
- data/test/{more/test_1stclassmethod.rb → core/kernel/test_method.rb} +2 -7
- data/test/core/kernel/test_tap.rb +1 -1
- data/test/core/proc/test_curry.rb +11 -0
- data/test/core/string/test_bytes.rb +1 -1
- data/test/core/string/test_camelcase.rb +23 -6
- data/test/core/string/test_lines.rb +1 -1
- data/test/core/string/test_unfold.rb +14 -0
- data/test/{more → core}/test_blank.rb +0 -0
- data/test/{more → core}/test_boolean.rb +0 -0
- data/test/{more → core}/test_functor.rb +0 -0
- data/test/{lore → more}/test_basicobject.rb +0 -0
- data/test/more/{test_class_extension.rb → test_class_extend.rb} +6 -6
- data/test/{lore → more}/test_continuation.rb +0 -0
- data/test/{lore → more}/test_date.rb +0 -0
- data/test/more/{test_enumerablepass.rb → test_enumargs.rb} +2 -4
- data/test/more/{test_equatable.rb → test_equitable.rb} +2 -2
- data/test/more/{test_instantise.rb → test_instance_function.rb} +3 -2
- data/test/more/test_memoize.rb +1 -1
- data/test/{lore → more}/test_ostruct.rb +0 -0
- metadata +865 -1016
- data/RELEASE +0 -38
- data/doc/README.lore +0 -51
- data/doc/log/basic_stats/index.html +0 -39
- data/doc/log/changelog.html +0 -648
- data/doc/log/changelog.txt +0 -217
- data/doc/log/stats/index.html +0 -39
- data/doc/log/testlog.txt +0 -278
- data/doc/notes/CHANGES +0 -2529
- data/doc/rdoc/lore/classes/Array.html +0 -176
- data/doc/rdoc/lore/classes/CGI.html +0 -191
- data/doc/rdoc/lore/classes/Config.html +0 -135
- data/doc/rdoc/lore/classes/Continuation.html +0 -113
- data/doc/rdoc/lore/classes/Date.html +0 -631
- data/doc/rdoc/lore/classes/DateTime.html +0 -583
- data/doc/rdoc/lore/classes/Enumerable.html +0 -89
- data/doc/rdoc/lore/classes/Enumerable/Enumerator.html +0 -147
- data/doc/rdoc/lore/classes/File.html +0 -128
- data/doc/rdoc/lore/classes/FileUtils.html +0 -434
- data/doc/rdoc/lore/classes/GetoptLong.html +0 -118
- data/doc/rdoc/lore/classes/GetoptLong/DSL.html +0 -208
- data/doc/rdoc/lore/classes/Kernel.html +0 -135
- data/doc/rdoc/lore/classes/Logger.html +0 -229
- data/doc/rdoc/lore/classes/Logger/Ansicolor.html +0 -277
- data/doc/rdoc/lore/classes/Logger/LogDevice.html +0 -121
- data/doc/rdoc/lore/classes/NilClass.html +0 -119
- data/doc/rdoc/lore/classes/OpenStruct.html +0 -432
- data/doc/rdoc/lore/classes/Pathname.html +0 -353
- data/doc/rdoc/lore/classes/Set.html +0 -117
- data/doc/rdoc/lore/classes/Shellwords.html +0 -111
- data/doc/rdoc/lore/classes/String.html +0 -140
- data/doc/rdoc/lore/classes/Time.html +0 -154
- data/doc/rdoc/lore/classes/URI.html +0 -454
- data/doc/rdoc/lore/classes/URI/Hash.html +0 -105
- data/doc/rdoc/lore/classes/URI/Kernel.html +0 -122
- data/doc/rdoc/lore/classes/Zlib.html +0 -188
- data/doc/rdoc/lore/created.rid +0 -1
- data/doc/rdoc/lore/files/README.html +0 -286
- data/doc/rdoc/lore/files/doc/README_lore.html +0 -155
- data/doc/rdoc/lore/files/lib/lore/facets/basicobject_rb.html +0 -118
- data/doc/rdoc/lore/files/lib/lore/facets/cgi_rb.html +0 -111
- data/doc/rdoc/lore/files/lib/lore/facets/continuation_rb.html +0 -147
- data/doc/rdoc/lore/files/lib/lore/facets/date_rb.html +0 -97
- data/doc/rdoc/lore/files/lib/lore/facets/enumerator_rb.html +0 -111
- data/doc/rdoc/lore/files/lib/lore/facets/fileutils/head_rb.html +0 -96
- data/doc/rdoc/lore/files/lib/lore/facets/fileutils/safe_ln_rb.html +0 -96
- data/doc/rdoc/lore/files/lib/lore/facets/fileutils/slice_rb.html +0 -96
- data/doc/rdoc/lore/files/lib/lore/facets/fileutils/tail_rb.html +0 -96
- data/doc/rdoc/lore/files/lib/lore/facets/fileutils/wc_rb.html +0 -96
- data/doc/rdoc/lore/files/lib/lore/facets/fileutils/whereis_rb.html +0 -96
- data/doc/rdoc/lore/files/lib/lore/facets/fileutils/which_rb.html +0 -96
- data/doc/rdoc/lore/files/lib/lore/facets/fileutils_rb.html +0 -131
- data/doc/rdoc/lore/files/lib/lore/facets/getoptlong_rb.html +0 -135
- data/doc/rdoc/lore/files/lib/lore/facets/logger_rb.html +0 -142
- data/doc/rdoc/lore/files/lib/lore/facets/ostruct_rb.html +0 -135
- data/doc/rdoc/lore/files/lib/lore/facets/pathname_rb.html +0 -145
- data/doc/rdoc/lore/files/lib/lore/facets/rbconfig_rb.html +0 -124
- data/doc/rdoc/lore/files/lib/lore/facets/set_rb.html +0 -96
- data/doc/rdoc/lore/files/lib/lore/facets/shellwords_rb.html +0 -124
- data/doc/rdoc/lore/files/lib/lore/facets/uri_rb.html +0 -125
- data/doc/rdoc/lore/files/lib/lore/facets/yaml_rb.html +0 -146
- data/doc/rdoc/lore/files/lib/lore/facets/zlib_rb.html +0 -97
- data/doc/rdoc/lore/fr_class_index.html +0 -73
- data/doc/rdoc/lore/fr_file_index.html +0 -71
- data/doc/rdoc/lore/fr_method_index.html +0 -177
- data/doc/rdoc/lore/index.html +0 -26
- data/doc/rdoc/lore/rdoc-style.css +0 -177
- data/doc/release-notes/RELEASE-2.0.5 +0 -8
- data/doc/release-notes/RELEASE-2.1.0 +0 -9
- data/doc/release-notes/RELEASE-2.1.1 +0 -5
- data/doc/release-notes/RELEASE-2.1.2 +0 -6
- data/doc/release-notes/RELEASE-2.1.3 +0 -5
- data/doc/release-notes/RELEASE-2.2.0 +0 -14
- data/doc/release-notes/RELEASE-2.2.1 +0 -4
- data/doc/release-notes/RELEASE-2.3.0 +0 -6
- data/doc/release-notes/RELEASE-2.4.0 +0 -70
- data/doc/release-notes/RELEASE-2.4.1 +0 -8
- data/doc/release-notes/RELEASE-2.4.2 +0 -4
- data/doc/release-notes/RELEASE-2.4.3 +0 -78
- data/doc/release-notes/RELEASE-2.4.4 +0 -38
- data/doc/release-notes/RELEASE-2.4.5 +0 -37
- data/doc/release-notes/RELEASE-2.5.0 +0 -83
- data/lib/core/facets/kernel/instance.rb +0 -19
- data/lib/lore/facets/basicobject.rb +0 -14
- data/lib/lore/facets/enumerator.rb +0 -67
- data/lib/lore/facets/logger.rb +0 -291
- data/lib/more/facets/1stclassmethod.rb +0 -140
- data/lib/more/facets/advisable.rb +0 -162
- data/lib/more/facets/association.rb +0 -210
- data/lib/more/facets/attr.rb +0 -209
- data/lib/more/facets/basex.rb +0 -37
- data/lib/more/facets/bbcode.rb +0 -397
- data/lib/more/facets/bicrypt.rb +0 -265
- data/lib/more/facets/binreadable.rb +0 -221
- data/lib/more/facets/censor.rb +0 -97
- data/lib/more/facets/classmethods.rb +0 -199
- data/lib/more/facets/consoleutils.rb +0 -99
- data/lib/more/facets/crypt.rb +0 -166
- data/lib/more/facets/dependency.rb +0 -151
- data/lib/more/facets/downloader.rb +0 -281
- data/lib/more/facets/duplicable.rb +0 -43
- data/lib/more/facets/elementor.rb +0 -133
- data/lib/more/facets/filter.rb +0 -121
- data/lib/more/facets/heap.rb +0 -22
- data/lib/more/facets/infinity.rb +0 -193
- data/lib/more/facets/ini.rb +0 -264
- data/lib/more/facets/instantise.rb +0 -1
- data/lib/more/facets/instantize.rb +0 -95
- data/lib/more/facets/interval.rb +0 -282
- data/lib/more/facets/iteration.rb +0 -65
- data/lib/more/facets/linkedlist.rb +0 -222
- data/lib/more/facets/lrucache.rb +0 -157
- data/lib/more/facets/matcher.rb +0 -140
- data/lib/more/facets/memoizer.rb +0 -74
- data/lib/more/facets/minitar.rb +0 -1063
- data/lib/more/facets/nackclass.rb +0 -41
- data/lib/more/facets/net/smtp_tls.rb +0 -131
- data/lib/more/facets/nilstatus.rb +0 -48
- data/lib/more/facets/overload.rb +0 -94
- data/lib/more/facets/paramix.rb +0 -202
- data/lib/more/facets/pool.rb +0 -91
- data/lib/more/facets/pqueue.rb +0 -449
- data/lib/more/facets/pry.rb +0 -32
- data/lib/more/facets/reflection.rb +0 -145
- data/lib/more/facets/semaphore.rb +0 -92
- data/lib/more/facets/settings.rb +0 -248
- data/lib/more/facets/snapshot.rb +0 -209
- data/lib/more/facets/sparse_array.rb +0 -809
- data/lib/more/facets/string/mask.rb +0 -278
- data/lib/more/facets/string/obfuscate.rb +0 -65
- data/lib/more/facets/string/stylize.rb +0 -169
- data/lib/more/facets/string/words.rb +0 -167
- data/lib/more/facets/syncarray.rb +0 -114
- data/lib/more/facets/synchash.rb +0 -157
- data/lib/more/facets/typecast.rb +0 -261
- data/lib/more/facets/uninheritable.rb +0 -50
- data/lib/more/facets/xmlhash.rb +0 -112
- data/lib/more/facets/xoxo.rb +0 -259
- data/lib/more/facets/ziputils.rb +0 -490
- data/task/conflicts +0 -63
- data/task/coverage.rake +0 -37
- data/task/methods +0 -49
- data/task/rdoc.rake +0 -17
- data/task/setup.rake +0 -38
- data/task/test.rake +0 -145
- data/test/more/test_advisable.rb +0 -71
- data/test/more/test_association.rb +0 -38
- data/test/more/test_bbcode.rb +0 -21
- data/test/more/test_binreadable.rb +0 -50
- data/test/more/test_buildable.rb +0 -73
- data/test/more/test_classmethods.rb +0 -56
- data/test/more/test_crypt.rb +0 -32
- data/test/more/test_dependency.rb +0 -69
- data/test/more/test_elementwise.rb +0 -25
- data/test/more/test_infinity.rb +0 -40
- data/test/more/test_interval.rb +0 -151
- data/test/more/test_linkedlist.rb +0 -41
- data/test/more/test_lrucache.rb +0 -14
- data/test/more/test_overload.rb +0 -160
- data/test/more/test_paramix.rb +0 -170
- data/test/more/test_prototype.rb +0 -35
- data/test/more/test_snapshot.rb +0 -21
- data/test/more/test_sparsearray.rb +0 -279
- data/test/more/test_syncarray.rb +0 -15
- data/test/more/test_synchash.rb +0 -16
- data/test/more/test_typecast.rb +0 -54
- data/test/more/test_uninheritable.rb +0 -31
- data/test/more/test_xoxo.rb +0 -274
- data/test/test_facets.rb +0 -9
@@ -1,167 +0,0 @@
|
|
1
|
-
require 'facets/string/fold'
|
2
|
-
|
3
|
-
class String
|
4
|
-
|
5
|
-
module Words
|
6
|
-
|
7
|
-
# Returns an array of characters.
|
8
|
-
#
|
9
|
-
# "abc 123".words #=> ["abc","123"]
|
10
|
-
#
|
11
|
-
def words
|
12
|
-
self.split(/\s+/)
|
13
|
-
end
|
14
|
-
|
15
|
-
# Iterate through each word of a string.
|
16
|
-
#
|
17
|
-
# "a string".each_word { |word, range| ... }
|
18
|
-
#
|
19
|
-
def each_word( &yld )
|
20
|
-
rest_of_string = self
|
21
|
-
wordfind = /([-'\w]+)/
|
22
|
-
arity = yld.arity
|
23
|
-
offset = 0
|
24
|
-
while wmatch = wordfind.match(rest_of_string)
|
25
|
-
word = wmatch[0]
|
26
|
-
range = offset+wmatch.begin(0) ... offset+wmatch.end(0)
|
27
|
-
rest_of_string = wmatch.post_match
|
28
|
-
if arity == 1
|
29
|
-
yld.call(word)
|
30
|
-
else
|
31
|
-
yld.call(word, range)
|
32
|
-
end
|
33
|
-
offset = self.length - rest_of_string.length
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
# Filters out words from a string based on block test.
|
38
|
-
#
|
39
|
-
# "a string".word_filter { |word| word =~ /^a/ } #=> "string"
|
40
|
-
#
|
41
|
-
# CREDIT: George Moschovitis
|
42
|
-
#
|
43
|
-
def word_filter( &blk )
|
44
|
-
s = self.dup
|
45
|
-
s.word_filter!( &blk )
|
46
|
-
end
|
47
|
-
|
48
|
-
# In place version of #word_filter.
|
49
|
-
#
|
50
|
-
# "a string".word_filter { |word| ... }
|
51
|
-
#
|
52
|
-
# CREDIT: George Moschovitis
|
53
|
-
|
54
|
-
def word_filter! #:yield:
|
55
|
-
rest_of_string = self
|
56
|
-
wordfind = /(\w+)/
|
57
|
-
offset = 0
|
58
|
-
while wmatch = wordfind.match(rest_of_string)
|
59
|
-
word = wmatch[0]
|
60
|
-
range = offset+wmatch.begin(0) ... offset+wmatch.end(0)
|
61
|
-
rest_of_string = wmatch.post_match
|
62
|
-
self[range] = yield( word ).to_s
|
63
|
-
offset = self.length - rest_of_string.length
|
64
|
-
end
|
65
|
-
self
|
66
|
-
end
|
67
|
-
|
68
|
-
# TODO: This is alternateive from glue: worth providing?
|
69
|
-
#
|
70
|
-
# Enforces a maximum width of a string inside an
|
71
|
-
# html container. If the string exceeds this maximum width
|
72
|
-
# the string gets wraped.
|
73
|
-
#
|
74
|
-
# Not really useful, better use the CSS overflow: hidden
|
75
|
-
# functionality.
|
76
|
-
#
|
77
|
-
# === Input:
|
78
|
-
# the string to be wrapped
|
79
|
-
# the enforced width
|
80
|
-
# the separator used for wrapping
|
81
|
-
#
|
82
|
-
# === Output:
|
83
|
-
# the wrapped string
|
84
|
-
#
|
85
|
-
# === Example:
|
86
|
-
# text = "1111111111111111111111111111111111111111111"
|
87
|
-
# text = wrap(text, 10, " ")
|
88
|
-
# p text # => "1111111111 1111111111 1111111111"
|
89
|
-
#
|
90
|
-
# See the test cases to better understand the behaviour!
|
91
|
-
|
92
|
-
# def wrap(width = 20, separator = " ")
|
93
|
-
# re = /([^#{separator}]{1,#{width}})/
|
94
|
-
# scan(re).join(separator)
|
95
|
-
# end
|
96
|
-
|
97
|
-
# Word wrap a string not exceeding max width.
|
98
|
-
#
|
99
|
-
# puts "this is a test".word_wrap(4)
|
100
|
-
#
|
101
|
-
# _produces_
|
102
|
-
#
|
103
|
-
# this
|
104
|
-
# is a
|
105
|
-
# test
|
106
|
-
#
|
107
|
-
# CREDIT: Gavin Kistner, Dayne Broderson
|
108
|
-
|
109
|
-
def word_wrap( col_width=80 )
|
110
|
-
self.dup.word_wrap!( col_width )
|
111
|
-
end
|
112
|
-
|
113
|
-
# As with #word_wrap, but modifies the string in place.
|
114
|
-
#
|
115
|
-
# CREDIT: Gavin Kistner, Dayne Broderson
|
116
|
-
|
117
|
-
def word_wrap!( col_width=80 )
|
118
|
-
self.gsub!( /(\S{#{col_width}})(?=\S)/, '\1 ' )
|
119
|
-
self.gsub!( /(.{1,#{col_width}})(?:\s+|$)/, "\\1\n" )
|
120
|
-
self
|
121
|
-
end
|
122
|
-
|
123
|
-
#--
|
124
|
-
# (OLD DEFINITION)
|
125
|
-
#
|
126
|
-
# def word_wrap!(max=80)
|
127
|
-
# raise ArgumentError, "Wrap margin too low: #{n}" if max <= 2
|
128
|
-
# #gsub!( Regexp.new( "(.{1,#{max-1}}\\w)\\b\\s*" ), "\\1\n")
|
129
|
-
# gsub!( /(.{1,#{max-1}}\S)([ ]|\n)/, "\\1\n")
|
130
|
-
# end
|
131
|
-
#
|
132
|
-
#++
|
133
|
-
|
134
|
-
# Returns short abstract of long strings; not exceeding +range+
|
135
|
-
# characters. If range is an integer then the minimum is 20%
|
136
|
-
# of the maximum. The string is chopped at the nearest word
|
137
|
-
# if possible, and appended by +ellipsis+, which defaults
|
138
|
-
# to '...'.
|
139
|
-
#
|
140
|
-
# CREDIT: George Moschovitis, Trans
|
141
|
-
|
142
|
-
def brief(range=76, ellipsis="...")
|
143
|
-
if Range===range
|
144
|
-
min = range.first
|
145
|
-
max = range.last
|
146
|
-
else
|
147
|
-
max = range
|
148
|
-
min = max - (max/5).to_i
|
149
|
-
range = min..max
|
150
|
-
end
|
151
|
-
|
152
|
-
if size > max
|
153
|
-
cut_at = rindex(/\b/, max) || max
|
154
|
-
cut_at = max if cut_at < min
|
155
|
-
xstring = slice(0, cut_at)
|
156
|
-
xstring.chomp(" ") + ellipsis
|
157
|
-
else
|
158
|
-
self
|
159
|
-
end
|
160
|
-
end
|
161
|
-
|
162
|
-
end
|
163
|
-
|
164
|
-
include Words
|
165
|
-
|
166
|
-
end
|
167
|
-
|
@@ -1,114 +0,0 @@
|
|
1
|
-
# = SyncArray
|
2
|
-
#
|
3
|
-
# A thread-safe array. We use a sync object instead of a
|
4
|
-
# mutex, because it is re-entrant. An exclusive lock is
|
5
|
-
# needed when writing, a shared lock IS NEEDED when reading.
|
6
|
-
#
|
7
|
-
# == Authors
|
8
|
-
#
|
9
|
-
# * George Moschovitis
|
10
|
-
#
|
11
|
-
# == Copyright
|
12
|
-
#
|
13
|
-
# Copyright (c) 2004 George Moschovitis
|
14
|
-
#
|
15
|
-
# Ruby License
|
16
|
-
#
|
17
|
-
# This module is free software. You may use, modify, and/or redistribute this
|
18
|
-
# software under the same terms as Ruby.
|
19
|
-
#
|
20
|
-
# This program is distributed in the hope that it will be useful, but WITHOUT
|
21
|
-
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
22
|
-
# FOR A PARTICULAR PURPOSE.
|
23
|
-
|
24
|
-
require 'sync'
|
25
|
-
|
26
|
-
# = SyncArray
|
27
|
-
#
|
28
|
-
# A thread-safe array. We use a sync object instead of a
|
29
|
-
# mutex, because it is re-entrant. An exclusive lock is
|
30
|
-
# needed when writing, a shared lock IS NEEDED when reading.
|
31
|
-
#
|
32
|
-
class Array
|
33
|
-
|
34
|
-
def self.mutable_methods
|
35
|
-
@mutable ||= %w{ << []= abbrev clear collect! compact! concat
|
36
|
-
delete delete_at delete_if fill flatten insert map! pop push
|
37
|
-
reject! replace reverse! shift slice! sort! transpose uniq!
|
38
|
-
unshift
|
39
|
-
}
|
40
|
-
end
|
41
|
-
|
42
|
-
end
|
43
|
-
|
44
|
-
class SyncArray < Array
|
45
|
-
|
46
|
-
attr :sync
|
47
|
-
|
48
|
-
#
|
49
|
-
# gmosx: delegator is not yet used.
|
50
|
-
#
|
51
|
-
def initialize(delegator = nil)
|
52
|
-
@sync = ::Sync.new()
|
53
|
-
super()
|
54
|
-
end
|
55
|
-
|
56
|
-
instance_methods.each do |m|
|
57
|
-
next if Object.instance_methods.include?(m)
|
58
|
-
if mutable_methods.include?(m)
|
59
|
-
sync_type = "Sync::EX"
|
60
|
-
else
|
61
|
-
sync_type = "Sync::SH"
|
62
|
-
end
|
63
|
-
class_eval %{
|
64
|
-
def #{m}(*args)
|
65
|
-
return @sync.synchronize(#{sync_type}) { super }
|
66
|
-
end
|
67
|
-
}
|
68
|
-
end
|
69
|
-
|
70
|
-
# def << (value)
|
71
|
-
# return @sync.synchronize(Sync::SH) { super }
|
72
|
-
# end
|
73
|
-
#
|
74
|
-
# def delete_if(&block)
|
75
|
-
# return @sync.synchronize(Sync::SH) { super }
|
76
|
-
# end
|
77
|
-
#
|
78
|
-
# def [](key)
|
79
|
-
# return @sync.synchronize(Sync::SH) { super }
|
80
|
-
# end
|
81
|
-
#
|
82
|
-
# def []=(key, value)
|
83
|
-
# return @sync.synchronize(Sync::EX) { super }
|
84
|
-
# end
|
85
|
-
#
|
86
|
-
# def delete(key)
|
87
|
-
# return @sync.synchronize(Sync::EX) { super }
|
88
|
-
# end
|
89
|
-
#
|
90
|
-
# def clear
|
91
|
-
# @sync.synchronize(Sync::EX) { super }
|
92
|
-
# end
|
93
|
-
#
|
94
|
-
# def size
|
95
|
-
# return @sync.synchronize(Sync::SH) { super }
|
96
|
-
# end
|
97
|
-
#
|
98
|
-
# def shift
|
99
|
-
# return @sync.synchronize(::Sync::EX) { super }
|
100
|
-
# end
|
101
|
-
#
|
102
|
-
# def unshift(el)
|
103
|
-
# return @sync.synchronize(::Sync::EX) { super }
|
104
|
-
# end
|
105
|
-
|
106
|
-
end
|
107
|
-
|
108
|
-
#--
|
109
|
-
# Funniest thing, remove the :: in front of Sync.new in the initialize
|
110
|
-
# routine and uncomment the alias line below and watch the stack blow chunks.
|
111
|
-
# I'm leaving this comment here as a reminder.
|
112
|
-
### Array::Sync = SyncArray
|
113
|
-
#++
|
114
|
-
|
data/lib/more/facets/synchash.rb
DELETED
@@ -1,157 +0,0 @@
|
|
1
|
-
# = SyncHash
|
2
|
-
#
|
3
|
-
# A thread-safe hash. We use a sync object instead of a mutex,
|
4
|
-
# because it is re-entrant. An exclusive lock is needed when
|
5
|
-
# writing, a shared lock IS NEEDED when reading.
|
6
|
-
#
|
7
|
-
# Uses the delegator pattern to allow for multiple
|
8
|
-
# implementations!
|
9
|
-
#
|
10
|
-
# hash = SyncHash.new
|
11
|
-
# hash = SyncHash.new(Hash.new) # Delegates
|
12
|
-
#
|
13
|
-
# == Design
|
14
|
-
#
|
15
|
-
# This class uses the delegator pattern. However we don't use Ruby's
|
16
|
-
# delegation facilities, they are more general and powerful than we
|
17
|
-
# need here (and slower). Instead a custom (but simple) solution is
|
18
|
-
# used.
|
19
|
-
#
|
20
|
-
# == Authors
|
21
|
-
#
|
22
|
-
# * George Moschovitis
|
23
|
-
#
|
24
|
-
# == Copyright
|
25
|
-
#
|
26
|
-
# Copyright (c) 2004 George Moschovitis
|
27
|
-
#
|
28
|
-
# Ruby License
|
29
|
-
#
|
30
|
-
# This module is free software. You may use, modify, and/or redistribute this
|
31
|
-
# software under the same terms as Ruby.
|
32
|
-
#
|
33
|
-
# This program is distributed in the hope that it will be useful, but WITHOUT
|
34
|
-
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
35
|
-
# FOR A PARTICULAR PURPOSE.
|
36
|
-
|
37
|
-
require 'sync'
|
38
|
-
|
39
|
-
# = SyncHash
|
40
|
-
#
|
41
|
-
# A thread-safe hash. We use a sync object instead of a mutex,
|
42
|
-
# because it is re-entrant. An exclusive lock is needed when
|
43
|
-
# writing, a shared lock IS NEEDED when reading.
|
44
|
-
#
|
45
|
-
# Uses the delegator pattern to allow for multiple
|
46
|
-
# implementations!
|
47
|
-
#
|
48
|
-
# hash = SyncHash.new
|
49
|
-
# hash = SyncHash.new(Hash.new) # Delegates
|
50
|
-
#
|
51
|
-
# == Design
|
52
|
-
#
|
53
|
-
# This class uses the delegator pattern. However we don't use Ruby's
|
54
|
-
# delegation facilities, they are more general and powerful than we
|
55
|
-
# need here (and slower). Instead a custom (but simple) solution is
|
56
|
-
# used.
|
57
|
-
#
|
58
|
-
# == Usage
|
59
|
-
#
|
60
|
-
# hash = SyncHash.new
|
61
|
-
# hash = SyncHash.new(Hash.new) # Delegates
|
62
|
-
#
|
63
|
-
class SyncHash < Hash
|
64
|
-
|
65
|
-
attr :delegate, :sync
|
66
|
-
|
67
|
-
def initialize(delegate=nil)
|
68
|
-
@delegate = delegate
|
69
|
-
@sync = ::Sync.new
|
70
|
-
if delegate
|
71
|
-
self.extend Delegator
|
72
|
-
else
|
73
|
-
self.extend Inheritor
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
# Is this even advisable ?
|
78
|
-
#def replace(new_delegate)
|
79
|
-
# self.extend Delegator unless @delegate
|
80
|
-
# # or? raise 'not a delegating synchash' unless @delegate
|
81
|
-
# @delegate = new_delegate
|
82
|
-
#end
|
83
|
-
|
84
|
-
# This module is used when a delegate is NOT being used.
|
85
|
-
module Inheritor
|
86
|
-
|
87
|
-
def [](key)
|
88
|
-
@sync.synchronize(::Sync::SH) { super }
|
89
|
-
end
|
90
|
-
|
91
|
-
def []=(key, value)
|
92
|
-
@sync.synchronize(::Sync::EX) { super }
|
93
|
-
end
|
94
|
-
|
95
|
-
def delete(key)
|
96
|
-
@sync.synchronize(::Sync::EX) { super }
|
97
|
-
end
|
98
|
-
|
99
|
-
def clear
|
100
|
-
@sync.synchronize(::Sync::EX) { super }
|
101
|
-
end
|
102
|
-
|
103
|
-
def size
|
104
|
-
@sync.synchronize(::Sync::SH) { super }
|
105
|
-
end
|
106
|
-
|
107
|
-
def values
|
108
|
-
@sync.synchronize(::Sync::SH) { super }
|
109
|
-
end
|
110
|
-
|
111
|
-
def keys
|
112
|
-
@sync.synchronize(::Sync::SH) { super }
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
# This module is used when a delegate is being used.
|
117
|
-
module Delegator
|
118
|
-
|
119
|
-
def [](key)
|
120
|
-
@sync.synchronize(::Sync::SH) { @delegate[key] }
|
121
|
-
end
|
122
|
-
|
123
|
-
def []=(key, value)
|
124
|
-
@sync.synchronize(::Sync::EX) { @delegate[key] = value }
|
125
|
-
end
|
126
|
-
|
127
|
-
def delete(key)
|
128
|
-
@sync.synchronize(::Sync::EX) { @delegate.delete(key) }
|
129
|
-
end
|
130
|
-
|
131
|
-
def clear
|
132
|
-
@sync.synchronize(::Sync::EX) { @delegate.clear }
|
133
|
-
end
|
134
|
-
|
135
|
-
def size
|
136
|
-
@sync.synchronize(::Sync::SH) { @delegate.size() }
|
137
|
-
end
|
138
|
-
|
139
|
-
def values
|
140
|
-
@sync.synchronize(::Sync::SH) { @delegate.values() }
|
141
|
-
end
|
142
|
-
|
143
|
-
def keys
|
144
|
-
@sync.synchronize(::Sync::SH) { @delegate.keys() }
|
145
|
-
end
|
146
|
-
|
147
|
-
end #module Delegator
|
148
|
-
|
149
|
-
end #class SyncHash
|
150
|
-
|
151
|
-
#--
|
152
|
-
# Funniest thing, remove the :: in front of Sync.new in the initialize
|
153
|
-
# routine and uncomment the alias line below and watch the stack blow chunks.
|
154
|
-
# I'm leaving this comment here as a reminder.
|
155
|
-
### Hash::Sync = SyncHash
|
156
|
-
#++
|
157
|
-
|
data/lib/more/facets/typecast.rb
DELETED
@@ -1,261 +0,0 @@
|
|
1
|
-
# = TypeCast
|
2
|
-
#
|
3
|
-
# Provides a generic simple type conversion utility. All the ruby core
|
4
|
-
# conversions are available by default.
|
5
|
-
#
|
6
|
-
# "1234".cast_to Float => 1234.0 (Float)
|
7
|
-
# Time.cast_from("6:30") => 1234.0 (Time)
|
8
|
-
#
|
9
|
-
# To implement a new type conversion, you have two choices, take:
|
10
|
-
#
|
11
|
-
# class CustomType
|
12
|
-
# def initialize(my_var)
|
13
|
-
# @my_var = my_var
|
14
|
-
# end
|
15
|
-
# end
|
16
|
-
#
|
17
|
-
# Define a to_class_name instance method
|
18
|
-
#
|
19
|
-
# class CustomType
|
20
|
-
# def to_string
|
21
|
-
# my_var.to_s
|
22
|
-
# end
|
23
|
-
# end
|
24
|
-
#
|
25
|
-
# c = CustomType.new 1234
|
26
|
-
# s.cast_to String => "1234" (String)
|
27
|
-
#
|
28
|
-
# Define a from_class_name class method
|
29
|
-
#
|
30
|
-
# class CustomType
|
31
|
-
# def self.from_string(str)
|
32
|
-
# self.new(str)
|
33
|
-
# end
|
34
|
-
# end
|
35
|
-
#
|
36
|
-
# "1234".cast_to CustomType => #<CustomType:0xb7d1958c @my_var="1234">
|
37
|
-
#
|
38
|
-
# Those two methods are equivalent in the result. It was coded like that to
|
39
|
-
# avoid the pollution of core classes with tons of to_* methods.
|
40
|
-
#
|
41
|
-
# The standard methods to_s, to_f, to_i, to_a and to_sym are also used by
|
42
|
-
# this system if available.
|
43
|
-
#
|
44
|
-
# == Faq
|
45
|
-
#
|
46
|
-
# Q. Why didn't you name the `cast_to` method to `to` ?
|
47
|
-
#
|
48
|
-
# A. Even if it would make the syntax more friendly, I suspect it could cause
|
49
|
-
# a lot of collisions with already existing code. The goal is that each
|
50
|
-
# time you call cast_to, you either get your result, either a
|
51
|
-
# TypeCastException
|
52
|
-
#
|
53
|
-
# == Authors
|
54
|
-
#
|
55
|
-
# * Jonas Pfenniger
|
56
|
-
#
|
57
|
-
# == History
|
58
|
-
#
|
59
|
-
# * 2006-06-06 3v1l_d4y:
|
60
|
-
# * Removed transformation options.
|
61
|
-
# * Removed StringIO typecast. It is not required by default.
|
62
|
-
# * Added TypeCastException for better error reporting while coding.
|
63
|
-
#
|
64
|
-
# == Todo
|
65
|
-
#
|
66
|
-
# * Consider how this might fit in with method signitures, overloading,
|
67
|
-
# and expiremental euphoria-like type system.
|
68
|
-
#
|
69
|
-
# * Look to implement to_int, to_mailtext, to_r, to_rfc822text and to_str.
|
70
|
-
#
|
71
|
-
# == Copying
|
72
|
-
#
|
73
|
-
# Copyright (c) 2004 Jonas Pfenniger
|
74
|
-
#
|
75
|
-
# Ruby License
|
76
|
-
#
|
77
|
-
# This module is free software. You may use, modify, and/or redistribute this
|
78
|
-
# software under the same terms as Ruby.
|
79
|
-
#
|
80
|
-
# This program is distributed in the hope that it will be useful, but WITHOUT
|
81
|
-
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
82
|
-
# FOR A PARTICULAR PURPOSE.
|
83
|
-
|
84
|
-
require 'time'
|
85
|
-
require 'facets/string/methodize'
|
86
|
-
require 'facets/string/camelcase' #modulize'
|
87
|
-
|
88
|
-
# = Typecast
|
89
|
-
#
|
90
|
-
# Provides a generic simple type conversion utility. All the ruby core
|
91
|
-
# conversions are available by default.
|
92
|
-
#
|
93
|
-
# "1234".cast_to Float => 1234.0 (Float)
|
94
|
-
# Time.cast_from("6:30") => 1234.0 (Time)
|
95
|
-
#
|
96
|
-
# To implement a new type conversion, you have two choices, take:
|
97
|
-
#
|
98
|
-
# class CustomType
|
99
|
-
# def initialize(my_var)
|
100
|
-
# @my_var = my_var
|
101
|
-
# end
|
102
|
-
# end
|
103
|
-
#
|
104
|
-
# Define a to_class_name instance method
|
105
|
-
#
|
106
|
-
# class CustomType
|
107
|
-
# def to_string
|
108
|
-
# my_var.to_s
|
109
|
-
# end
|
110
|
-
# end
|
111
|
-
#
|
112
|
-
# c = CustomType.new 1234
|
113
|
-
# s.cast_to String => "1234" (String)
|
114
|
-
#
|
115
|
-
# Define a from_class_name class method
|
116
|
-
#
|
117
|
-
# class CustomType
|
118
|
-
# def self.from_string(str)
|
119
|
-
# self.new(str)
|
120
|
-
# end
|
121
|
-
# end
|
122
|
-
#
|
123
|
-
# "1234".cast_to CustomType => #<CustomType:0xb7d1958c @my_var="1234">
|
124
|
-
#
|
125
|
-
# Those two methods are equivalent in the result. It was coded like that to
|
126
|
-
# avoid the pollution of core classes with tons of to_* methods.
|
127
|
-
#
|
128
|
-
# The standard methods to_s, to_f, to_i, to_a and to_sym are also used by
|
129
|
-
# this system if available.
|
130
|
-
#
|
131
|
-
# == Faq
|
132
|
-
#
|
133
|
-
# Q. Why didn't you name the `cast_to` method to `to` ?
|
134
|
-
#
|
135
|
-
# A. Even if it would make the syntax more friendly, I suspect it could cause
|
136
|
-
# a lot of collisions with already existing code. The goal is that each
|
137
|
-
# time you call cast_to, you either get your result, either a
|
138
|
-
# TypeCastException
|
139
|
-
#
|
140
|
-
module TypeCast
|
141
|
-
|
142
|
-
# Typecast method extensions for Object class.
|
143
|
-
|
144
|
-
module Object
|
145
|
-
# Cast an object to another
|
146
|
-
#
|
147
|
-
# 1234.cast_to(String) => "1234"
|
148
|
-
#
|
149
|
-
def cast_to(klass)
|
150
|
-
klass.cast_from(self)
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
# Typecast method extensions for Class class.
|
155
|
-
|
156
|
-
module Class
|
157
|
-
# Cast on object from another.
|
158
|
-
#
|
159
|
-
# String.cast_from(1234) => "1234"
|
160
|
-
#
|
161
|
-
def cast_from(object)
|
162
|
-
method_to = "to_#{self.name.methodize}".to_sym
|
163
|
-
if object.respond_to? method_to
|
164
|
-
retval = object.send(method_to)
|
165
|
-
return retval
|
166
|
-
end
|
167
|
-
method_from = "from_#{object.class.name.methodize}".to_sym
|
168
|
-
if respond_to? method_from
|
169
|
-
retval = send(method_from, object)
|
170
|
-
return retval
|
171
|
-
end
|
172
|
-
raise TypeCastException, "TypeCasting from #{object.class.name} to #{self.name} not supported"
|
173
|
-
end
|
174
|
-
end
|
175
|
-
|
176
|
-
end
|
177
|
-
|
178
|
-
# TypeCast Exception error.
|
179
|
-
#
|
180
|
-
class TypeCastException < Exception; end
|
181
|
-
|
182
|
-
class Object #:nodoc:
|
183
|
-
include TypeCast::Object
|
184
|
-
end
|
185
|
-
|
186
|
-
class Class #:nodoc:
|
187
|
-
include TypeCast::Class
|
188
|
-
end
|
189
|
-
|
190
|
-
class Array #:nodoc:
|
191
|
-
def self.cast_from(object)
|
192
|
-
return super
|
193
|
-
rescue TypeCastException
|
194
|
-
return object.to_a if object.respond_to? :to_a
|
195
|
-
raise
|
196
|
-
end
|
197
|
-
end
|
198
|
-
|
199
|
-
class Float #:nodoc:
|
200
|
-
def self.cast_from(object)
|
201
|
-
return super
|
202
|
-
rescue TypeCastException
|
203
|
-
return object.to_f if object.respond_to? :to_f
|
204
|
-
raise
|
205
|
-
end
|
206
|
-
end
|
207
|
-
|
208
|
-
class Integer #:nodoc:
|
209
|
-
def self.cast_from(object)
|
210
|
-
return super
|
211
|
-
rescue TypeCastException
|
212
|
-
return object.to_i if object.respond_to? :to_i
|
213
|
-
raise
|
214
|
-
end
|
215
|
-
end
|
216
|
-
|
217
|
-
class String #:nodoc:
|
218
|
-
def self.cast_from(object)
|
219
|
-
return super
|
220
|
-
rescue TypeCastException
|
221
|
-
return object.to_s if object.respond_to? :to_s
|
222
|
-
raise
|
223
|
-
end
|
224
|
-
end
|
225
|
-
|
226
|
-
class Symbol #:nodoc:
|
227
|
-
def self.cast_from(object)
|
228
|
-
return super
|
229
|
-
rescue TypeCastException
|
230
|
-
return object.to_sym if object.respond_to? :to_sym
|
231
|
-
raise
|
232
|
-
end
|
233
|
-
end
|
234
|
-
|
235
|
-
# Special Extensions
|
236
|
-
|
237
|
-
class Class #:nodoc:
|
238
|
-
# "string".cast_to Class #=> String
|
239
|
-
def self.from_string(string)
|
240
|
-
string = string.to_s.camelcase #modulize
|
241
|
-
base = string.sub!(/^::/, '') ? Object : (self.kind_of?(Module) ? self : self.class )
|
242
|
-
klass = string.split(/::/).inject(base){ |mod, name| mod.const_get(name) }
|
243
|
-
return klass if klass.kind_of? Class
|
244
|
-
nil
|
245
|
-
rescue
|
246
|
-
nil
|
247
|
-
end
|
248
|
-
|
249
|
-
class << self
|
250
|
-
alias_method :from_symbol, :from_string
|
251
|
-
end
|
252
|
-
end
|
253
|
-
|
254
|
-
class Time #:nodoc:
|
255
|
-
def self.from_string(string, options={})
|
256
|
-
parse(string)
|
257
|
-
rescue
|
258
|
-
nil
|
259
|
-
end
|
260
|
-
end
|
261
|
-
|