facets 2.9.3 → 3.0.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.
- checksums.yaml +7 -0
- data/.index +76 -0
- data/CONTRIBUTE.md +78 -0
- data/HISTORY.md +2459 -0
- data/{RUBY.txt → LICENSE.txt} +0 -0
- data/README.rdoc +29 -7
- data/demo/applique/assertion_framework.rb +1 -0
- data/{qed → demo}/applique/file_helpers.rb +0 -0
- data/{qed → demo}/core/array/combination.rdoc +0 -0
- data/{qed → demo}/core/array/delete.rdoc +0 -0
- data/{qed → demo}/core/array/index.rdoc +0 -0
- data/{qed → demo}/core/array/merge.rdoc +0 -0
- data/{qed → demo}/core/array/only.rdoc +0 -0
- data/{qed → demo}/core/array/pad.rdoc +0 -0
- data/{qed → demo}/core/array/permutation.rdoc +0 -0
- data/{qed → demo}/core/array/product.rdoc +0 -0
- data/{qed → demo}/core/array/recursively.rdoc +0 -0
- data/{qed → demo}/core/array/rotate.rdoc +0 -0
- data/{qed → demo}/core/array/select.rdoc +0 -0
- data/{qed → demo}/core/array/uniq_by.rdoc +0 -0
- data/{qed → demo}/core/binding/caller.rdoc +0 -0
- data/{qed → demo}/core/binding/defined.rdoc +0 -0
- data/{qed → demo}/core/binding/eval.rdoc +0 -0
- data/{qed → demo}/core/binding/local_variables.rdoc +0 -0
- data/{qed → demo}/core/binding/opvars.rdoc +0 -0
- data/{qed → demo}/core/binding/self.rdoc +0 -0
- data/{qed → demo}/core/class/descendants.rdoc +0 -0
- data/{qed → demo}/core/class/to_proc.rdoc +0 -0
- data/{qed → demo}/core/comparable/cap.rdoc +0 -0
- data/{qed → demo}/core/comparable/clip.rdoc +0 -0
- data/{qed → demo}/core/comparable/cmp.rdoc +0 -0
- data/{qed → demo}/core/comparable/op_get.rdoc +0 -0
- data/{qed → demo}/core/dir/ascend.rdoc +0 -0
- data/{qed → demo}/core/dir/descend.rdoc +0 -0
- data/{qed → demo}/core/dir/multiglob.rdoc +0 -0
- data/{qed → demo}/core/dir/parent.rdoc +0 -0
- data/{qed → demo}/core/dir/recurse.rdoc +0 -0
- data/{qed → demo}/core/exception/detail.rdoc +0 -0
- data/{qed → demo}/core/facets.rdoc +0 -0
- data/{qed → demo}/core/filetest/root.rdoc +0 -0
- data/{qed → demo}/core/hash/recursively.rdoc +0 -0
- data/{qed → demo}/core/indexable.rdoc +0 -0
- data/{qed → demo}/core/integer/bitmask.rdoc +0 -0
- data/{qed → demo}/core/integer/even.rdoc +0 -0
- data/{qed → demo}/core/integer/factorial.rdoc +0 -0
- data/{qed → demo}/core/integer/length.rdoc +0 -0
- data/{qed → demo}/core/integer/multiple.rdoc +0 -0
- data/{qed → demo}/core/integer/odd.rdoc +0 -0
- data/{qed → demo}/core/integer/of.rdoc +0 -0
- data/{qed → demo}/core/integer/ordinal.rdoc +0 -0
- data/{qed → demo}/core/matchdata/match.rdoc +0 -0
- data/{qed → demo}/core/matchdata/matchset.rdoc +0 -0
- data/{qed → demo}/core/module/cattr.rdoc +0 -0
- data/{qed → demo}/core/module/class_extend.rdoc +0 -0
- data/{qed → demo}/core/module/class_inheritor.rdoc +0 -0
- data/{qed → demo}/core/module/copy_inheritor.rdoc +0 -0
- data/{qed → demo}/core/module/method_space.rdoc +0 -0
- data/{qed → demo}/core/string/align.rdoc +0 -0
- data/{qed → demo}/core/string/bracket.rdoc +0 -0
- data/{qed → demo}/core/string/bytes.rdoc +0 -0
- data/{qed → demo}/core/string/camelcase.rdoc +0 -0
- data/{qed → demo}/core/string/capitalized.rdoc +0 -0
- data/{qed → demo}/core/string/characters.rdoc +0 -0
- data/{qed → demo}/core/string/cleanlines.rdoc +0 -0
- data/{qed → demo}/core/string/cleave.rdoc +0 -0
- data/{qed → demo}/core/string/divide.rdoc +0 -0
- data/{qed → demo}/core/string/each_char.rdoc +0 -0
- data/{qed → demo}/core/string/each_word.rdoc +0 -0
- data/{qed → demo}/core/string/end_with.rdoc +0 -0
- data/{qed → demo}/core/string/expand_tabs.rdoc +0 -0
- data/{qed → demo}/core/string/fold.rdoc +0 -0
- data/{qed → demo}/core/string/indent.rdoc +0 -0
- data/{qed → demo}/core/string/interpolate.rdoc +0 -0
- data/{qed → demo}/core/string/lchomp.rdoc +0 -0
- data/{qed → demo}/core/string/line_wrap.rdoc +0 -0
- data/{qed → demo}/core/string/lines.rdoc +0 -0
- data/{qed → demo}/core/string/margin.rdoc +0 -0
- data/{qed → demo}/core/string/methodize.rdoc +0 -0
- data/{qed → demo}/core/string/modulize.rdoc +0 -0
- data/{qed → demo}/core/string/mscan.rdoc +0 -0
- data/{qed → demo}/core/string/natcmp.rdoc +0 -0
- data/{qed → demo}/core/string/nchar.rdoc +0 -0
- data/{qed → demo}/core/string/newlines.rdoc +0 -0
- data/{qed → demo}/core/string/op_sub.rdoc +0 -0
- data/{qed → demo}/core/string/pathize.rdoc +0 -0
- data/{qed → demo}/core/string/quote.rdoc +0 -0
- data/{qed → demo}/core/string/range.rdoc +0 -0
- data/{qed → demo}/core/string/rewrite.rdoc +0 -0
- data/{qed → demo}/core/string/shatter.rdoc +0 -0
- data/{qed → demo}/core/string/snakecase.rdoc +0 -0
- data/{qed → demo}/core/string/splice.rdoc +0 -0
- data/{qed → demo}/core/string/start_with.rdoc +0 -0
- data/{qed → demo}/core/string/subtract.rdoc +0 -0
- data/{qed → demo}/core/string/tab.rdoc +0 -0
- data/{qed → demo}/core/string/tabto.rdoc +0 -0
- data/{qed → demo}/core/string/titlecase.rdoc +0 -0
- data/{qed → demo}/core/string/to_re.rdoc +0 -0
- data/{qed → demo}/core/string/unfold.rdoc +0 -0
- data/{qed → demo}/core/string/unindent.rdoc +0 -0
- data/{qed → demo}/core/string/unquote.rdoc +0 -0
- data/{qed → demo}/core/string/variablize.rdoc +0 -0
- data/{qed → demo}/core/string/word_wrap.rdoc +0 -0
- data/{qed → demo}/core/string/words.rdoc +0 -0
- data/{qed → demo}/core/string/xor.rdoc +0 -0
- data/{qed → demo}/standard/02_cloneable.rdoc +0 -0
- data/{qed → demo}/standard/03_enumargs.rdoc +0 -0
- data/{qed → demo}/standard/04_equitable.rdoc +0 -0
- data/{qed → demo}/standard/05_instantiable.rdoc +0 -0
- data/{qed → demo}/standard/basic_object.rdoc +0 -0
- data/{qed → demo}/standard/memoizable.rdoc +0 -0
- data/{qed → demo}/standard/mulititon.rdoc +0 -0
- data/lib/core/facets.rb +1 -2
- data/lib/core/facets.yml +61 -42
- data/lib/core/facets/array.rb +8 -28
- data/lib/core/facets/array/arrange.rb +42 -0
- data/lib/core/facets/array/before.rb +2 -0
- data/lib/core/facets/array/collapse.rb +2 -0
- data/lib/core/facets/array/commonality.rb +24 -12
- data/lib/core/facets/array/duplicates.rb +22 -1
- data/lib/core/facets/array/each_overlap.rb +25 -0
- data/lib/core/facets/array/intersection.rb +25 -0
- data/lib/core/facets/array/missing.rb +29 -0
- data/lib/core/facets/array/nonuniq.rb +7 -53
- data/lib/core/facets/array/occur.rb +38 -0
- data/lib/core/facets/array/occurrence.rb +28 -0
- data/lib/core/facets/array/only.rb +12 -1
- data/lib/core/facets/array/recursively.rb +11 -5
- data/lib/core/facets/array/reject_values.rb +21 -0
- data/lib/core/facets/array/splice.rb +5 -1
- data/lib/core/facets/array/split.rb +5 -2
- data/lib/core/facets/array/squeeze.rb +23 -0
- data/lib/core/facets/array/step.rb +31 -0
- data/lib/core/facets/array/store.rb +4 -0
- data/lib/core/facets/array/to_h.rb +22 -0
- data/lib/core/facets/array/traverse.rb +11 -5
- data/lib/core/facets/array/uniq_by.rb +5 -1
- data/lib/core/facets/array/unique_permutation.rb +29 -0
- data/lib/core/facets/array/zip.rb +21 -0
- data/lib/core/facets/binding.rb +0 -3
- data/lib/core/facets/binding/call_stack.rb +1 -1
- data/lib/core/facets/binding/caller.rb +1 -3
- data/lib/core/facets/binding/callstack.rb +1 -1
- data/lib/core/facets/binding/defined.rb +0 -2
- data/lib/core/facets/binding/local_variables.rb +0 -2
- data/lib/core/facets/binding/op_get.rb +0 -2
- data/lib/core/facets/binding/self.rb +1 -3
- data/lib/core/facets/cattr.rb +1 -0
- data/lib/core/facets/class.rb +0 -2
- data/lib/core/facets/class/cattr.rb +1 -0
- data/lib/core/facets/class/singleton.rb +1 -13
- data/lib/core/facets/class/singleton_class.rb +16 -0
- data/lib/core/facets/comparable.rb +0 -2
- data/lib/core/facets/dir.rb +0 -2
- data/lib/core/facets/dir/ascend.rb +2 -2
- data/lib/core/facets/dir/lookup.rb +20 -0
- data/lib/core/facets/enumerable.rb +10 -9
- data/lib/core/facets/enumerable/accumulate.rb +18 -16
- data/lib/core/facets/enumerable/apply.rb +20 -0
- data/lib/core/facets/enumerable/associate.rb +6 -0
- data/lib/core/facets/enumerable/cluster.rb +24 -0
- data/lib/core/facets/enumerable/every.rb +1 -1
- data/lib/core/facets/enumerable/ewise.rb +2 -0
- data/lib/core/facets/enumerable/graph.rb +0 -3
- data/lib/core/facets/enumerable/hashify.rb +222 -19
- data/lib/core/facets/enumerable/hinge.rb +18 -0
- data/lib/core/facets/enumerable/key_by.rb +27 -0
- data/lib/core/facets/enumerable/map_to.rb +13 -0
- data/lib/core/facets/enumerable/mash.rb +34 -1
- data/lib/core/facets/enumerable/occur.rb +12 -9
- data/lib/core/facets/enumerable/only.rb +56 -0
- data/lib/core/facets/enumerable/{cluster_by.rb → organize_by.rb} +5 -4
- data/lib/core/facets/enumerable/pair.rb +20 -0
- data/lib/core/facets/enumerable/per.rb +27 -35
- data/lib/core/facets/enumerable/recursively.rb +3 -3
- data/lib/core/facets/enumerable/squeeze.rb +36 -0
- data/lib/core/facets/enumerable/sum.rb +18 -6
- data/lib/core/facets/enumerable/unassociate.rb +23 -0
- data/lib/core/facets/enumerable/value_by.rb +25 -0
- data/lib/core/facets/enumerator/fx.rb +16 -25
- data/lib/core/facets/enumerator/lazy/squeeze.rb +33 -0
- data/lib/core/facets/essentials.rb +65 -0
- data/lib/core/facets/exception.rb +0 -2
- data/lib/core/facets/exception/set_message.rb +10 -0
- data/lib/core/facets/file.rb +1 -2
- data/lib/core/facets/file/common_path.rb +17 -0
- data/lib/core/facets/file/rootname.rb +1 -1
- data/lib/core/facets/filetest.rb +0 -2
- data/lib/core/facets/filetest/relative.rb +1 -1
- data/lib/core/facets/filetest/safe.rb +14 -10
- data/lib/core/facets/float.rb +1 -3
- data/lib/core/facets/float/round_to.rb +1 -0
- data/lib/core/facets/functor.rb +8 -10
- data/lib/core/facets/hash.rb +2 -5
- data/lib/core/facets/hash/collate.rb +22 -8
- data/lib/core/facets/hash/count.rb +8 -4
- data/lib/core/facets/hash/data.rb +5 -2
- data/lib/core/facets/hash/dearray_values.rb +1 -1
- data/lib/core/facets/hash/deep_rekey.rb +54 -0
- data/lib/core/facets/hash/each_with_key.rb +12 -0
- data/lib/core/facets/hash/fetch_nested.rb +20 -0
- data/lib/core/facets/hash/keys.rb +4 -13
- data/lib/core/facets/hash/only_keys.rb +1 -0
- data/lib/core/facets/hash/op_push.rb +9 -1
- data/lib/core/facets/hash/op_sub.rb +1 -1
- data/lib/core/facets/hash/recursively.rb +6 -6
- data/lib/core/facets/hash/rekey.rb +26 -34
- data/lib/core/facets/hash/revalue.rb +61 -0
- data/lib/core/facets/hash/slice.rb +16 -3
- data/lib/core/facets/hash/subset.rb +11 -8
- data/lib/core/facets/hash/update_each.rb +1 -1
- data/lib/core/facets/hash/weave.rb +1 -1
- data/lib/core/facets/indexable.rb +6 -6
- data/lib/core/facets/integer.rb +0 -4
- data/lib/core/facets/kernel.rb +4 -7
- data/lib/core/facets/kernel/__dir__.rb +2 -0
- data/lib/core/facets/kernel/as.rb +2 -1
- data/lib/core/facets/kernel/call_stack.rb +1 -56
- data/lib/core/facets/kernel/callstack.rb +56 -1
- data/lib/core/facets/kernel/constant.rb +2 -0
- data/lib/core/facets/kernel/deep_clone.rb +27 -1
- data/lib/core/facets/kernel/deep_copy.rb +0 -24
- data/lib/core/facets/kernel/eigen.rb +2 -33
- data/lib/core/facets/kernel/eigenclass.rb +1 -1
- data/lib/core/facets/kernel/ergo.rb +1 -1
- data/lib/core/facets/kernel/extend.rb +4 -6
- data/lib/core/facets/kernel/instance_assign.rb +8 -6
- data/lib/core/facets/kernel/instance_extract.rb +22 -0
- data/lib/core/facets/kernel/instance_replace.rb +40 -0
- data/lib/core/facets/kernel/{equate.rb → like.rb} +7 -4
- data/lib/core/facets/kernel/load_relative.rb +25 -1
- data/lib/core/facets/kernel/meta.rb +35 -0
- data/lib/core/facets/kernel/meta_def.rb +4 -0
- data/lib/core/facets/kernel/object_send.rb +11 -14
- data/lib/core/facets/kernel/respond.rb +3 -13
- data/lib/core/facets/kernel/tap.rb +27 -39
- data/lib/core/facets/load_path.rb +1 -0
- data/lib/core/facets/load_path/search.rb +16 -0
- data/lib/core/facets/matchdata.rb +0 -2
- data/lib/core/facets/method.rb +0 -2
- data/lib/core/facets/method/composition.rb +32 -16
- data/lib/core/facets/method/curry.rb +13 -0
- data/lib/core/facets/method/partial.rb +10 -0
- data/lib/core/facets/method/public.rb +33 -0
- data/lib/core/facets/module.rb +0 -2
- data/lib/core/facets/module/alias_class_method.rb +11 -0
- data/lib/core/facets/module/basename.rb +1 -31
- data/lib/core/facets/module/cattr.rb +1 -0
- data/lib/core/facets/module/lastname.rb +30 -0
- data/lib/core/facets/module/mattr.rb +4 -4
- data/lib/core/facets/nilclass.rb +0 -3
- data/lib/core/facets/numeric.rb +0 -4
- data/lib/core/facets/numeric/approx.rb +3 -2
- data/lib/core/facets/numeric/range.rb +12 -0
- data/lib/core/facets/numeric/round_to.rb +32 -1
- data/lib/core/facets/object.rb +2 -3
- data/lib/core/facets/object/itself.rb +16 -0
- data/lib/core/facets/objectspace.rb +0 -3
- data/lib/core/facets/proc.rb +0 -3
- data/lib/core/facets/proc/bind_to.rb +3 -3
- data/lib/core/facets/proc/wrap.rb +17 -0
- data/lib/core/facets/process.rb +0 -2
- data/lib/core/facets/range.rb +4 -4
- data/lib/core/facets/range/op_add.rb +15 -0
- data/lib/core/facets/range/op_sub.rb +45 -0
- data/lib/core/facets/range/{to_r.rb → to_rng.rb} +1 -1
- data/lib/core/facets/regexp.rb +0 -2
- data/lib/core/facets/regexp/to_proc.rb +13 -0
- data/lib/core/facets/string.rb +8 -9
- data/lib/core/facets/string/ascii_only.rb +52 -0
- data/lib/core/facets/string/each_match.rb +1 -0
- data/lib/core/facets/string/ends_with.rb +1 -0
- data/lib/core/facets/string/file.rb +6 -20
- data/lib/core/facets/string/fold.rb +5 -5
- data/lib/core/facets/string/indent.rb +37 -20
- data/lib/core/facets/string/indexable.rb +7 -0
- data/lib/core/facets/string/interpolate.rb +6 -2
- data/lib/core/facets/string/linear.rb +19 -0
- data/lib/core/facets/string/margin.rb +47 -19
- data/lib/core/facets/string/mscan.rb +3 -0
- data/lib/core/facets/string/number.rb +14 -0
- data/lib/core/facets/string/op_sub.rb +1 -14
- data/lib/core/facets/string/random.rb +34 -0
- data/lib/core/facets/string/remove.rb +30 -0
- data/lib/core/facets/string/rotate.rb +24 -0
- data/lib/core/facets/string/similarity.rb +2 -2
- data/lib/core/facets/string/starts_with.rb +5 -0
- data/lib/core/facets/string/tab.rb +2 -17
- data/lib/core/facets/string/tabto.rb +2 -19
- data/lib/core/facets/string/to_rx.rb +1 -0
- data/lib/core/facets/string/trim.rb +45 -0
- data/lib/core/facets/string/unfold.rb +7 -2
- data/lib/core/facets/struct.rb +1 -2
- data/lib/core/facets/struct/replace.rb +8 -0
- data/lib/core/facets/symbol.rb +1 -3
- data/lib/core/facets/symbol/as_s.rb +3 -1
- data/lib/core/facets/symbol/call.rb +29 -0
- data/lib/core/facets/symbol/thrown.rb +9 -5
- data/lib/core/facets/time.rb +0 -2
- data/lib/core/facets/time/future.rb +6 -4
- data/lib/core/facets/unboundmethod.rb +0 -3
- data/lib/core/facets/version.rb +5 -5
- data/lib/standard/facets/against.rb +53 -0
- data/lib/standard/facets/binding/block_exec.rb +44 -0
- data/lib/standard/facets/cgi.rb +2 -40
- data/lib/standard/facets/cgi/esc.rb +11 -0
- data/lib/standard/facets/cgi/escape_html.rb +63 -0
- data/lib/standard/facets/cgi/marshal.rb +20 -0
- data/lib/standard/facets/cli.rb +54 -0
- data/lib/standard/facets/cloneable.rb +12 -9
- data/lib/standard/facets/enumargs.rb +159 -168
- data/lib/standard/facets/find.rb +1 -15
- data/lib/standard/facets/find/select.rb +16 -0
- data/lib/standard/facets/gem/search.rb +18 -0
- data/lib/standard/facets/gem/specification/current_specs.rb +21 -0
- data/lib/standard/facets/gem/specification/find_requireable_file.rb +21 -0
- data/lib/standard/facets/hash_builder.rb +46 -0
- data/lib/standard/facets/load_monitor.rb +26 -0
- data/lib/standard/facets/math.rb +57 -57
- data/lib/standard/facets/math/acosec.rb +1 -0
- data/lib/standard/facets/math/acsc.rb +6 -1
- data/lib/standard/facets/math/beta.rb +8 -3
- data/lib/standard/facets/math/cosec.rb +1 -0
- data/lib/standard/facets/math/cosech.rb +1 -0
- data/lib/standard/facets/math/csc.rb +6 -1
- data/lib/standard/facets/math/csch.rb +6 -1
- data/lib/standard/facets/math/distance.rb +19 -0
- data/lib/standard/facets/math/ec.rb +5 -0
- data/lib/standard/facets/math/lgamma.rb +21 -21
- data/lib/standard/facets/math/lngamma.rb +18 -0
- data/lib/standard/facets/math/pow.rb +6 -1
- data/lib/standard/facets/math/root.rb +1 -1
- data/lib/standard/facets/math/sign.rb +15 -4
- data/lib/standard/facets/math/tau.rb +5 -0
- data/lib/standard/facets/math/tgamma.rb +1 -1
- data/lib/standard/facets/memoizer.rb +63 -0
- data/lib/standard/facets/ostruct.rb +37 -156
- data/lib/standard/facets/ostruct/each.rb +11 -0
- data/lib/standard/facets/ostruct/initialize.rb +48 -0
- data/lib/standard/facets/ostruct/merge.rb +21 -0
- data/lib/standard/facets/ostruct/op_fetch.rb +29 -0
- data/lib/standard/facets/ostruct/op_store.rb +1 -0
- data/lib/standard/facets/ostruct/to_h.rb +10 -0
- data/lib/standard/facets/ostruct/to_ostruct.rb +65 -0
- data/lib/standard/facets/pathname.rb +18 -215
- data/lib/standard/facets/pathname/chdir.rb +15 -0
- data/lib/standard/facets/pathname/empty.rb +10 -0
- data/lib/standard/facets/pathname/exists.rb +6 -0
- data/lib/standard/facets/pathname/glob.rb +57 -0
- data/lib/standard/facets/pathname/home.rb +12 -0
- data/lib/standard/facets/pathname/null.rb +20 -0
- data/lib/standard/facets/pathname/op_div.rb +15 -0
- data/lib/standard/facets/pathname/op_fetch.rb +13 -0
- data/lib/standard/facets/pathname/outofdate.rb +13 -0
- data/lib/standard/facets/pathname/readline.rb +13 -0
- data/lib/standard/facets/pathname/root.rb +10 -0
- data/lib/standard/facets/pathname/rootname.rb +10 -0
- data/lib/standard/facets/pathname/safe.rb +15 -0
- data/lib/standard/facets/pathname/split_root.rb +9 -0
- data/lib/standard/facets/pathname/to_path.rb +28 -0
- data/lib/standard/facets/pathname/to_str.rb +8 -0
- data/lib/standard/facets/pathname/uptodate.rb +11 -0
- data/lib/standard/facets/pathname/visit.rb +38 -0
- data/lib/standard/facets/pathname/work.rb +10 -0
- data/lib/standard/facets/platform.rb +2 -2
- data/lib/standard/facets/random.rb +32 -2
- data/lib/standard/facets/shellwords.rb +5 -2
- data/lib/standard/facets/thread.rb +2 -2
- data/lib/standard/facets/uri.rb +7 -178
- data/lib/standard/facets/uri/cgi_escape.rb +46 -0
- data/lib/standard/facets/uri/cgi_parse.rb +1 -0
- data/lib/standard/facets/uri/cgi_unescape.rb +1 -0
- data/lib/standard/facets/uri/decode.rb +32 -0
- data/lib/standard/facets/uri/parameters.rb +63 -0
- data/lib/standard/facets/uri/query.rb +148 -0
- data/lib/standard/facets/yaml.rb +3 -56
- data/lib/standard/facets/yaml/file.rb +41 -0
- data/lib/standard/facets/yaml/kernel.rb +29 -0
- data/lib/standard/facets/yaml/read.rb +12 -0
- data/test/core/array/test_arrange.rb +37 -0
- data/test/core/array/test_each_overlap.rb +31 -0
- data/test/core/array/test_intersection.rb +19 -0
- data/test/core/array/test_missing.rb +12 -0
- data/test/core/array/test_occur.rb +52 -0
- data/test/core/array/test_occurrence.rb +20 -0
- data/test/core/array/test_reject_values.rb +17 -0
- data/test/core/array/test_squeeze.rb +22 -0
- data/test/core/array/test_step.rb +28 -0
- data/test/core/array/test_unique_permutation.rb +23 -0
- data/test/core/enumerable/test_key_by.rb +22 -0
- data/test/core/enumerable/test_occur.rb +18 -5
- data/test/core/enumerable/test_only.rb +40 -0
- data/test/core/enumerable/test_squeeze.rb +35 -0
- data/test/core/enumerable/test_sum.rb +8 -3
- data/test/core/enumerator/lazy/test_squeeze.rb +33 -0
- data/test/core/hash/test_count.rb +10 -1
- data/test/core/hash/test_deep_rekey.rb +131 -0
- data/test/core/hash/test_each_with_key.rb +16 -0
- data/test/core/hash/test_fetch_nested.rb +24 -0
- data/test/core/hash/test_keys.rb +0 -11
- data/test/core/hash/test_rekey.rb +41 -1
- data/test/core/hash/test_revalue.rb +98 -0
- data/test/core/hash/test_slice.rb +12 -1
- data/test/core/kernel/test_deep_clone.rb +31 -0
- data/test/core/kernel/test_deep_copy.rb +2 -28
- data/test/core/kernel/test_instance_extract.rb +28 -0
- data/test/core/method/test_composition.rb +42 -0
- data/test/core/range/test_op_add.rb +24 -0
- data/test/core/range/test_op_sub.rb +34 -0
- data/test/core/string/test_ascii_only.rb +30 -0
- data/test/core/string/test_margin.rb +4 -104
- data/test/core/string/test_number.rb +44 -0
- data/test/core/string/test_remove.rb +36 -0
- data/test/core/string/test_rotate.rb +31 -0
- data/test/core/string/test_trim.rb +116 -0
- data/test/core/symbol/test_thrown.rb +22 -0
- data/test/standard/binding/test_block_exec.rb +21 -0
- data/test/standard/math/test_acot.rb +23 -0
- data/test/standard/math/test_acoth.rb +22 -0
- data/test/standard/math/test_beta.rb +19 -0
- data/test/standard/math/test_ceil.rb +22 -0
- data/test/standard/math/test_cosec.rb +19 -0
- data/test/standard/math/test_cosech.rb +19 -0
- data/test/standard/math/test_cot.rb +13 -0
- data/test/standard/math/test_coth.rb +13 -0
- data/test/standard/math/test_distance.rb +16 -0
- data/test/standard/math/test_exp10.rb +14 -0
- data/test/standard/math/test_exp2.rb +14 -0
- data/test/standard/math/test_factorial.rb +13 -0
- data/test/standard/math/test_floor.rb +23 -0
- data/test/standard/math/test_gcd.rb +18 -0
- data/test/standard/math/test_lcm.rb +13 -0
- data/test/standard/math/test_pow.rb +30 -0
- data/test/standard/math/test_root.rb +15 -0
- data/test/standard/math/test_sec.rb +19 -0
- data/test/standard/math/test_sech.rb +19 -0
- data/test/standard/math/test_sign.rb +6 -0
- data/test/standard/math/test_sinc.rb +15 -0
- data/test/standard/math/test_srq.rb +20 -0
- data/test/standard/pathname/test_chdir.rb +16 -0
- data/test/standard/pathname/test_readline.rb +23 -0
- data/test/standard/test_enumargs.rb +1 -1
- data/test/standard/test_math.rb +3 -0
- data/test/standard/test_ostruct.rb +26 -21
- data/test/standard/test_uri.rb +9 -0
- metadata +802 -183
- data/.ruby +0 -54
- data/HISTORY.rdoc +0 -2386
- data/lib/core/facets/array/combination.rb +0 -43
- data/lib/core/facets/array/index.rb +0 -23
- data/lib/core/facets/array/occurent.rb +0 -1
- data/lib/core/facets/array/permutation.rb +0 -32
- data/lib/core/facets/array/product.rb +0 -30
- data/lib/core/facets/array/rotate.rb +0 -48
- data/lib/core/facets/array/select.rb +0 -20
- data/lib/core/facets/binding/eval.rb +0 -14
- data/lib/core/facets/enumerable/count.rb +0 -53
- data/lib/core/facets/enumerable/each_with_object.rb +0 -38
- data/lib/core/facets/enumerable/group_by.rb +0 -33
- data/lib/core/facets/enumerable/none.rb +0 -32
- data/lib/core/facets/enumerable/one.rb +0 -39
- data/lib/core/facets/enumerable/take.rb +0 -16
- data/lib/core/facets/float/round.rb +0 -2
- data/lib/core/facets/hash/select.rb +0 -17
- data/lib/core/facets/hash/to_h.rb +0 -1
- data/lib/core/facets/hash/url_params.rb +0 -21
- data/lib/core/facets/instance.rb +0 -157
- data/lib/core/facets/integer/even.rb +0 -1
- data/lib/core/facets/integer/odd.rb +0 -37
- data/lib/core/facets/kernel/__callee__.rb +0 -1
- data/lib/core/facets/kernel/__method__.rb +0 -48
- data/lib/core/facets/kernel/require_relative.rb +0 -52
- data/lib/core/facets/kernel/source_location.rb +0 -13
- data/lib/core/facets/nilclass/to_f.rb +0 -17
- data/lib/core/facets/numeric/round.rb +0 -69
- data/lib/core/facets/numeric/round_at.rb +0 -1
- data/lib/core/facets/object/replace.rb +0 -43
- data/lib/core/facets/objectspace/reflect.rb +0 -62
- data/lib/core/facets/proc/curry.rb +0 -32
- data/lib/core/facets/string/bytes.rb +0 -21
- data/lib/core/facets/string/each_char.rb +0 -31
- data/lib/core/facets/string/end_with.rb +0 -1
- data/lib/core/facets/string/lines.rb +0 -19
- data/lib/core/facets/string/random_binary.rb +0 -10
- data/lib/core/facets/string/start_with.rb +0 -60
- data/lib/core/facets/symbol/to_proc.rb +0 -33
- data/lib/core/facets/to_hash.rb +0 -336
- data/lib/core/facets/unboundmethod/name.rb +0 -28
- data/lib/standard/facets/math/gamma.rb +0 -12
- data/test/core/array/test_occurent.rb +0 -33
- data/test/core/kernel/test_source_location.rb +0 -25
- data/test/core/string/test_tabto.rb +0 -16
@@ -2,45 +2,47 @@ require 'facets/functor'
|
|
2
2
|
|
3
3
|
module Enumerable
|
4
4
|
|
5
|
+
# TODO: Should Enumerable#accumuate be moved to a functor gem?"
|
6
|
+
|
5
7
|
# Accumulate a set of a set. For example, in an ORM design
|
6
8
|
# where `Group has_many User` we might have something
|
7
9
|
# equivalent to the following.
|
8
10
|
#
|
9
|
-
#
|
10
|
-
#
|
11
|
+
# Group = Struct.new(:users)
|
12
|
+
# User = Struct.new(:name, :friends)
|
11
13
|
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
14
|
+
# user1 = User.new('John', [])
|
15
|
+
# user2 = User.new('Jane', ['Jill'])
|
16
|
+
# user3 = User.new('Joe' , ['Jack', 'Jim'])
|
15
17
|
#
|
16
|
-
#
|
17
|
-
#
|
18
|
+
# group1 = Group.new([user1, user2])
|
19
|
+
# group2 = Group.new([user2, user3])
|
18
20
|
#
|
19
|
-
#
|
21
|
+
# groups = [group1, group2]
|
20
22
|
#
|
21
23
|
# Now we can *accumulate* the users of all groups.
|
22
24
|
#
|
23
|
-
#
|
25
|
+
# groups.accumulate.users #=> [user1, user2, user3]
|
24
26
|
#
|
25
27
|
# You may pass an argument to perform chains, e.g. the following
|
26
28
|
# returns the names of users from all groups.
|
27
29
|
#
|
28
|
-
#
|
30
|
+
# groups.accumulate(2).users.name #=> ['John','Jane','Joe']
|
29
31
|
#
|
30
32
|
# Or we can gather all the friends of all users in groups.
|
31
33
|
#
|
32
|
-
#
|
34
|
+
# groups.accumulate(2).users.friends #=> ['Jill','Jack','Jim']
|
33
35
|
#
|
34
36
|
# This is more convenient then the equivalent.
|
35
37
|
#
|
36
|
-
#
|
38
|
+
# groups.accumulate.users.accumulate.friends #=> ['Jill','Jack','Jim']
|
37
39
|
#
|
38
|
-
# CREDIT: George Moshchovitis, Daniel Emirikol
|
40
|
+
# CREDIT: George Moshchovitis, Daniel Emirikol, Robert Dober
|
39
41
|
|
40
42
|
def accumulate(iterations=1)
|
41
43
|
return self if iterations == 0
|
44
|
+
|
42
45
|
Functor.new do |op, *args|
|
43
|
-
#result = inject([]) { |a, x| a << x.send(op, *args) }.flatten.uniq
|
44
46
|
result = []
|
45
47
|
each { |x| result << x.send(op, *args) }
|
46
48
|
result.flatten.uniq.accumulate(iterations - 1)
|
@@ -49,12 +51,12 @@ module Enumerable
|
|
49
51
|
|
50
52
|
# Same as #accumulate, but does not apply #uniq to final result.
|
51
53
|
#
|
52
|
-
#
|
54
|
+
# groups.accumulate_all(2).users.friends #=> ['Jill', 'Jill','Jack','Jim']
|
53
55
|
#
|
54
56
|
def accumulate_all(iterations=1)
|
55
57
|
return self if iterations == 0
|
58
|
+
|
56
59
|
Functor.new do |op, *args|
|
57
|
-
#result = inject([]) { |a, x| a << x.send(op, *args) }.flatten
|
58
60
|
result = []
|
59
61
|
each { |x| result << x.send(op, *args) }
|
60
62
|
result.flatten.accumulate_all(iterations - 1)
|
@@ -0,0 +1,20 @@
|
|
1
|
+
#require 'facets/functor'
|
2
|
+
require 'facets/enumerable/per'
|
3
|
+
|
4
|
+
module Enumerable
|
5
|
+
|
6
|
+
# Returns an elemental object. This allows
|
7
|
+
# you to map a method on to every element.
|
8
|
+
#
|
9
|
+
# r = [1,2,3].apply.+
|
10
|
+
# r #=> 6
|
11
|
+
#
|
12
|
+
def apply
|
13
|
+
#Functor.new do |sym, *args, &blk|
|
14
|
+
# inject{ |r, e| r.__send__(sym, e, *args, &blk) }
|
15
|
+
#end
|
16
|
+
per(:inject)
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Enumerable
|
2
|
+
|
3
|
+
# Clusters together adjacent elements into a list of
|
4
|
+
# sub-arrays.
|
5
|
+
#
|
6
|
+
# >> [2,2,2,3,3,4,2,2,1].cluster{ |x| x }
|
7
|
+
# => [[2, 2, 2], [3, 3], [4], [2, 2], [1]]
|
8
|
+
#
|
9
|
+
# @author Oleg K
|
10
|
+
|
11
|
+
def cluster
|
12
|
+
cluster = []
|
13
|
+
each do |element|
|
14
|
+
if cluster.last && yield(cluster.last.last) == yield(element)
|
15
|
+
cluster.last << element
|
16
|
+
else
|
17
|
+
cluster << [element]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
cluster
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
@@ -2,6 +2,8 @@ require 'facets/functor'
|
|
2
2
|
|
3
3
|
module Enumerable
|
4
4
|
|
5
|
+
# TODO: Should Enumerable#ewise be moved to functor gem?"
|
6
|
+
|
5
7
|
# Returns an elementwise Functor designed to make R-like
|
6
8
|
# elementwise operations possible. This is very much like
|
7
9
|
# the #every method, but it treats array argument specially.
|
@@ -1,31 +1,234 @@
|
|
1
|
+
#require 'facets/enumerator'
|
2
|
+
require 'facets/hash/dearray_values'
|
3
|
+
require 'facets/enumerable/value_by'
|
4
|
+
|
1
5
|
module Enumerable
|
2
|
-
|
3
|
-
#
|
6
|
+
|
7
|
+
# The hashify methods is a higher-order message used to
|
8
|
+
# convert an enumerable object into a hash. Converting an
|
9
|
+
# enumerable object into a hash is not a one-to-one conversion,
|
10
|
+
# for this reason #hashify is used to provide variant approches
|
11
|
+
# for the conversion most suited to the use case at hand.
|
12
|
+
# Here are some (but not a complete set of) examples.
|
13
|
+
#
|
14
|
+
# If the enumerable is a collection of perfect pairs, like that
|
15
|
+
# which Hash#to_a generates, then #assoc can be used.
|
16
|
+
#
|
17
|
+
# a = [ [:a,1], [:b,2] ]
|
18
|
+
# a.hashify.assoc #=> { :a=>1, :b=>2 }
|
4
19
|
#
|
5
|
-
# If
|
6
|
-
#
|
20
|
+
# If it it contains only arrays, but are not perfect pairs,
|
21
|
+
# then #concat can be used.
|
7
22
|
#
|
8
|
-
#
|
9
|
-
#
|
23
|
+
# a = [ [:a,1,2], [:b,2], [:c], [:d] ]
|
24
|
+
# a.hashify.concat #=> { :a=>[1,2], :b=>[2], :c=>[], :d=>[] }
|
10
25
|
#
|
11
|
-
# If
|
12
|
-
#
|
26
|
+
# If the array contians objects other then arrays then
|
27
|
+
# the #splat method might do the trick.
|
13
28
|
#
|
14
|
-
#
|
29
|
+
# a = [ [:a,1,2], 2, :b, [:c,3], 9 ]
|
30
|
+
# a.hashify.splat #=> { [:a,1,2]=>2, :b=>[:c,3], 9=>nil }
|
15
31
|
#
|
16
|
-
#
|
32
|
+
# Also, the particular dispatch can be left up the Hashify
|
33
|
+
# using the #auto method. See Hashify#auto for details on this.
|
17
34
|
#
|
18
|
-
#
|
19
|
-
#
|
35
|
+
# TODO: This method takes arguments only for the sake of the old
|
36
|
+
# method which has been deprecated. These will be removed eventually.
|
20
37
|
#
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
38
|
+
# CREDIT: Robert Klemme, Sandor Szücs, Trans
|
39
|
+
|
40
|
+
def hashify(val=nil, &block)
|
41
|
+
if val
|
42
|
+
warn "The old Enumerable#hashify method has been be deprecated. Use #value_by instead."
|
43
|
+
value_by{ val }
|
44
|
+
end
|
45
|
+
|
46
|
+
if block
|
47
|
+
warn "The old Enumerable#hashify method has been be deprecated. Use #value_by instead."
|
48
|
+
value_by(&block)
|
27
49
|
end
|
28
|
-
|
50
|
+
|
51
|
+
Hashifier.new(self)
|
52
|
+
end
|
53
|
+
|
54
|
+
#
|
55
|
+
class Hashifier
|
56
|
+
|
57
|
+
def initialize(enum)
|
58
|
+
@enum = enum
|
59
|
+
end
|
60
|
+
|
61
|
+
# This is equivalent to Hash[*array], but it will pad
|
62
|
+
# the array with a +nil+ object if there are not an even number
|
63
|
+
# of elements.
|
64
|
+
#
|
65
|
+
# a = [:a,1,:b,2,:c]
|
66
|
+
# a.to_h_splat #=> { :a=>1, :b=>2, :c=>nil }
|
67
|
+
#
|
68
|
+
# TODO: Can this be done without #size?
|
69
|
+
def splat
|
70
|
+
a = @enum.dup
|
71
|
+
a << nil if a.size % 2 == 1
|
72
|
+
Hash[*a]
|
73
|
+
end
|
74
|
+
|
75
|
+
# This is equivalent to Hash[*array.flatten], but it will pad
|
76
|
+
# the array with a +nil+ object if there are not an even number
|
77
|
+
# of elements.
|
78
|
+
#
|
79
|
+
# a = [:a,1,[:b,2,:c]]
|
80
|
+
# a.to_h_flat #=> { :a=>1, :b=>2, :c=>nil }
|
81
|
+
#
|
82
|
+
# TODO: Need to do this without #size.
|
83
|
+
def flat
|
84
|
+
a = @enum.flatten
|
85
|
+
a << nil if a.size % 2 == 1
|
86
|
+
Hash[*a]
|
87
|
+
end
|
88
|
+
|
89
|
+
# When a mixed or multi-element accociative array
|
90
|
+
# is used, the result is as follows:
|
91
|
+
#
|
92
|
+
# a = [ [:a,1,2], [:b,2], [:c], :d ]
|
93
|
+
# a.hashify.assoc #=> { :a=>[1,2], :b=>[2], :c=>[], :d=>[] }
|
94
|
+
#
|
95
|
+
# If the first entry of any subelements are the same, then
|
96
|
+
# the value will be set to the last occuring value.
|
97
|
+
#
|
98
|
+
# a = [ :x, [:x], [:x,1,2], [:x,3], [:x,4] ]
|
99
|
+
# a.hashify.assoc #=> { :x=>[4] }
|
100
|
+
#
|
101
|
+
def associate
|
102
|
+
h = {}
|
103
|
+
each do |k,*v|
|
104
|
+
h[k] = v
|
105
|
+
end
|
106
|
+
h
|
107
|
+
end
|
108
|
+
|
109
|
+
# Alias for #associate.
|
110
|
+
alias :assoc, :associate
|
111
|
+
|
112
|
+
# Like associate but does force values into an array.
|
113
|
+
#
|
114
|
+
def merge
|
115
|
+
h = {}
|
116
|
+
each do |k,v|
|
117
|
+
h[k] = v
|
118
|
+
end
|
119
|
+
h
|
120
|
+
end
|
121
|
+
|
122
|
+
# When a mixed or multi-element accociative array
|
123
|
+
# is used, the result is as follows:
|
124
|
+
#
|
125
|
+
# a = [ [:a,1,2], [:b,2], [:c], :d ]
|
126
|
+
# a.hashify.concat #=> { :a=>[1,2], :b=>[2], :c=>[], :d=>[] }
|
127
|
+
#
|
128
|
+
# If the first entry of the subelements is the same, then
|
129
|
+
# the values will be merged using #concat.
|
130
|
+
#
|
131
|
+
# a = [ [:a,1,2], [:a,3], [:a,4], [:a], :a ]
|
132
|
+
# a.hasify.concat #=> { :a=>[1,2,3,4] }
|
133
|
+
#
|
134
|
+
def concat
|
135
|
+
h = {}
|
136
|
+
each do |k,*v|
|
137
|
+
h[k] ||= []
|
138
|
+
h[k].concat(v)
|
139
|
+
end
|
140
|
+
h
|
141
|
+
end
|
142
|
+
|
143
|
+
# Older name for #concat.
|
144
|
+
alias :multi, :concat
|
145
|
+
|
146
|
+
# Convert enumerable object to Hash using index as keys.
|
147
|
+
#
|
148
|
+
# [:a, :b, :c].hashify.by_index #=> {1=>:a, 2=>:b, 3=>:c}
|
149
|
+
#
|
150
|
+
def by_index
|
151
|
+
h = {}
|
152
|
+
each_with_index do |v, i|
|
153
|
+
h[i] = v
|
154
|
+
end
|
155
|
+
h
|
156
|
+
end
|
157
|
+
|
158
|
+
# Converts enumerable object into a hash. Converting an array
|
159
|
+
# into a hash is not a one-to-one conversion, for this
|
160
|
+
# reason #auto examines the enumerable being converted
|
161
|
+
# and then dispatches the conversion to the most sutiable
|
162
|
+
# specialized function. There are three possiblities for this.
|
163
|
+
#
|
164
|
+
# If the enumerable is a collection of perfect pairs, like that
|
165
|
+
# which Hash#to_a generates, then conversion is handled by
|
166
|
+
# #flat.
|
167
|
+
#
|
168
|
+
# a = [ [:a,1], [:b,2] ]
|
169
|
+
# a.hashify.auto #=> { :a=>1, :b=>2 }
|
170
|
+
#
|
171
|
+
# If it contains only arrays, but are not perfect pairs,
|
172
|
+
# then #multi is called.
|
173
|
+
#
|
174
|
+
# a = [ [:a,1,2], [:b,2], [:c], [:d] ]
|
175
|
+
# a.hashify.auto #=> { :a=>[1,2], :b=>[2], :c=>[], :d=>[] }
|
176
|
+
#
|
177
|
+
# If it contians objects other then arrays then the #splat method
|
178
|
+
# is called.
|
179
|
+
#
|
180
|
+
# a = [ [:a,1,2], 2, :b, [:c,3], 9 ]
|
181
|
+
# a.hashify.auto #=> { [:a,1,2]=>2, :b=>[:c,3], 9=>nil }
|
182
|
+
#
|
183
|
+
# Be aware this is not as efficient as using the underlying methods
|
184
|
+
# directly becuase it must perform an initial iteration over the
|
185
|
+
# enumerable to determine its contents.
|
186
|
+
|
187
|
+
def auto(&block)
|
188
|
+
pairs, mixed = true, false
|
189
|
+
|
190
|
+
each do |e|
|
191
|
+
case e
|
192
|
+
when Array
|
193
|
+
pairs = false if e.size > 2
|
194
|
+
else
|
195
|
+
mixed = true
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
if mixed
|
200
|
+
splat(&block)
|
201
|
+
elsif pairs
|
202
|
+
flat(&block)
|
203
|
+
else
|
204
|
+
multi(&block)
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
# Alias for `#auto`.
|
209
|
+
alias :automatic, :auto
|
210
|
+
|
211
|
+
private
|
212
|
+
|
213
|
+
#
|
214
|
+
def each(&b)
|
215
|
+
@enum.each(&b)
|
216
|
+
end
|
217
|
+
|
218
|
+
#
|
219
|
+
def each_with_index(&b)
|
220
|
+
@enum.each_with_index(&b)
|
221
|
+
end
|
222
|
+
|
29
223
|
end
|
30
224
|
|
31
225
|
end
|
226
|
+
|
227
|
+
|
228
|
+
#class Enumerator
|
229
|
+
# # See `Enumerable#hashify`.
|
230
|
+
# def hashify
|
231
|
+
# Hashifier.new(self)
|
232
|
+
# end
|
233
|
+
#end
|
234
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Enumerable
|
2
|
+
|
3
|
+
# Apply each element of an enumerable ot a hash
|
4
|
+
# by iterating over each element and yielding
|
5
|
+
# the hash and element.
|
6
|
+
#
|
7
|
+
# [1,2,3].hinge{|h,e| h[e] = e+1 }
|
8
|
+
# #=> {1=>2, 2=>3, 3=>4}
|
9
|
+
#
|
10
|
+
# TODO: Enumerable#hinge will get a new name.
|
11
|
+
#
|
12
|
+
def hinge(init={})
|
13
|
+
h = init
|
14
|
+
each{ |v| yield(h,v) }
|
15
|
+
h
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Enumerable
|
2
|
+
|
3
|
+
# Convert enumerable into a Hash, iterating over each member
|
4
|
+
# where the provided block must return the key to by used
|
5
|
+
# to map to the value.
|
6
|
+
#
|
7
|
+
# Examples:
|
8
|
+
#
|
9
|
+
# [:a,:b,:c].key_by{ |v| v.to_s }
|
10
|
+
# #=> {'a'=>:a, 'b'=>:b, 'c'=>:c}
|
11
|
+
#
|
12
|
+
# TODO: How should this method behave with a Hash?
|
13
|
+
#
|
14
|
+
# Returns: Hash
|
15
|
+
|
16
|
+
def key_by
|
17
|
+
return to_enum(:key_by) unless block_given?
|
18
|
+
|
19
|
+
h = {}
|
20
|
+
each do |v|
|
21
|
+
h[yield(v)] = v
|
22
|
+
end
|
23
|
+
|
24
|
+
return h
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|