facets 1.3.0 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +11 -0
- data/ProjectInfo +2 -2
- data/Rakefile +3 -1
- data/conf/facets/noauto +28 -13
- data/data/facets/index.yml +3 -4
- data/lib/facet/array/pot.rb +1 -0
- data/lib/facet/builderobject.rb +1 -0
- data/lib/facet/module/this.rb +1 -0
- data/lib/facet/rexmlbuilder.rb +1 -0
- data/lib/facet/string/pot.rb +1 -0
- data/lib/facets/core/array.rb +1 -1
- data/lib/facets/core/array/{slap.rb → pot.rb} +8 -7
- data/lib/facets/core/date.rb +6 -0
- data/lib/facets/core/fileutils.rb +8 -0
- data/lib/facets/core/gem.rb +3 -0
- data/lib/facets/core/kernel/autoreload.rb +5 -5
- data/lib/facets/core/logger.rb +2 -0
- data/lib/facets/core/module.rb +1 -1
- data/lib/facets/core/module/{let.rb → this.rb} +21 -12
- data/lib/facets/core/ostruct.rb +7 -0
- data/lib/facets/core/string.rb +1 -2
- data/lib/facets/core/string/{slap.rb → pot.rb} +10 -9
- data/lib/facets/core/string/to_a.rb +13 -7
- data/lib/facets/more/basicobject.rb +2 -0
- data/lib/facets/more/builderobject.rb +216 -0
- data/lib/facets/more/functor.rb +13 -12
- data/lib/facets/more/multiton.rb +5 -5
- data/lib/facets/more/progressbar.rb +7 -1
- data/lib/facets/more/rexmlbuilder.rb +104 -0
- data/lib/facets/more/tuple.rb +219 -55
- data/lib/facets/more/units.rb +2 -1
- data/test/lib/facets/core/array/test_at_rand.rb +1 -1
- data/test/lib/facets/core/array/test_delete_unless.rb +1 -1
- data/test/lib/facets/core/array/test_delete_values.rb +1 -1
- data/test/lib/facets/core/array/test_delete_values_at.rb +1 -1
- data/test/lib/facets/core/array/test_first.rb +1 -1
- data/test/lib/facets/core/array/test_head.rb +1 -1
- data/test/lib/facets/core/array/test_last_index.rb +1 -1
- data/test/lib/facets/core/array/test_merge.rb +1 -1
- data/test/lib/facets/core/array/test_mid.rb +1 -1
- data/test/lib/facets/core/array/test_middle.rb +1 -1
- data/test/lib/facets/core/array/test_op_fetch.rb +1 -1
- data/test/lib/facets/core/array/test_op_store.rb +1 -1
- data/test/lib/facets/core/array/test_pick.rb +1 -1
- data/test/lib/facets/core/array/test_pos.rb +1 -1
- data/test/lib/facets/core/array/test_pot.rb +28 -0
- data/test/lib/facets/core/array/test_pull.rb +1 -1
- data/test/lib/facets/core/array/test_rand_index.rb +1 -1
- data/test/lib/facets/core/array/test_rand_subset.rb +1 -1
- data/test/lib/facets/core/array/test_range.rb +1 -1
- data/test/lib/facets/core/array/test_rotate.rb +1 -1
- data/test/lib/facets/core/array/test_select.rb +1 -1
- data/test/lib/facets/core/array/test_shuffle.rb +1 -1
- data/test/lib/facets/core/array/test_thru.rb +1 -1
- data/test/lib/facets/core/array/test_to_b.rb +1 -1
- data/test/lib/facets/core/array/test_to_h.rb +1 -1
- data/test/lib/facets/core/array/test_to_hash.rb +1 -1
- data/test/lib/facets/core/binding/self/test_of_caller.rb +1 -1
- data/test/lib/facets/core/binding/test___LINE__.rb +1 -1
- data/test/lib/facets/core/binding/test_call_stack.rb +1 -1
- data/test/lib/facets/core/binding/test_called.rb +1 -1
- data/test/lib/facets/core/binding/test_caller.rb +1 -1
- data/test/lib/facets/core/binding/test_defined.rb +1 -1
- data/test/lib/facets/core/binding/test_eval.rb +1 -1
- data/test/lib/facets/core/binding/test_local_variables.rb +1 -1
- data/test/lib/facets/core/binding/test_method_name.rb +1 -1
- data/test/lib/facets/core/binding/test_op_fetch.rb +1 -1
- data/test/lib/facets/core/binding/test_op_store.rb +1 -1
- data/test/lib/facets/core/binding/test_self.rb +1 -1
- data/test/lib/facets/core/class/test_cattr.rb +1 -1
- data/test/lib/facets/core/class/test_descendents.rb +1 -1
- data/test/lib/facets/core/class/test_method_name.rb +1 -1
- data/test/lib/facets/core/class/test_remove_descendents.rb +1 -1
- data/test/lib/facets/core/class/test_unix_path.rb +1 -1
- data/test/lib/facets/core/comparable/test_at_least.rb +1 -1
- data/test/lib/facets/core/comparable/test_clip.rb +1 -1
- data/test/lib/facets/core/comparable/test_cmp.rb +1 -1
- data/test/lib/facets/core/continuation/self/test_create.rb +1 -1
- data/test/lib/facets/core/date/test_days_in_month.rb +1 -1
- data/test/lib/facets/core/date/test_days_of_month.rb +1 -1
- data/test/lib/facets/core/date/test_stamp.rb +1 -1
- data/test/lib/facets/core/date/test_to_date.rb +1 -1
- data/test/lib/facets/core/date/test_to_s.rb +1 -1
- data/test/lib/facets/core/date/test_to_time.rb +1 -1
- data/test/lib/facets/core/dir/self/test_ancestor.rb +1 -1
- data/test/lib/facets/core/dir/self/test_ascend.rb +1 -1
- data/test/lib/facets/core/enumerable/self/test_combinations.rb +1 -1
- data/test/lib/facets/core/enumerable/self/test_cross.rb +1 -1
- data/test/lib/facets/core/enumerable/test_collect_with_index.rb +1 -1
- data/test/lib/facets/core/enumerable/test_commonality.rb +1 -1
- data/test/lib/facets/core/enumerable/test_compact_collect.rb +1 -1
- data/test/lib/facets/core/enumerable/test_cross.rb +1 -1
- data/test/lib/facets/core/enumerable/test_each_combination.rb +1 -1
- data/test/lib/facets/core/enumerable/test_each_pair.rb +1 -1
- data/test/lib/facets/core/enumerable/test_each_slice.rb +1 -1
- data/test/lib/facets/core/enumerable/test_each_unique_pair.rb +1 -1
- data/test/lib/facets/core/enumerable/test_entropy.rb +1 -1
- data/test/lib/facets/core/enumerable/test_every.rb +1 -1
- data/test/lib/facets/core/enumerable/test_ew.rb +1 -1
- data/test/lib/facets/core/enumerable/test_filter_collect.rb +1 -1
- data/test/lib/facets/core/enumerable/test_find_collisions.rb +1 -1
- data/test/lib/facets/core/enumerable/test_frequency.rb +1 -1
- data/test/lib/facets/core/enumerable/test_graph.rb +1 -1
- data/test/lib/facets/core/enumerable/test_ideal_entropy.rb +1 -1
- data/test/lib/facets/core/enumerable/test_none.rb +1 -1
- data/test/lib/facets/core/enumerable/test_occur.rb +1 -1
- data/test/lib/facets/core/enumerable/test_one.rb +1 -1
- data/test/lib/facets/core/enumerable/test_op_pow.rb +1 -1
- data/test/lib/facets/core/enumerable/test_partition_by.rb +1 -1
- data/test/lib/facets/core/enumerable/test_permute.rb +1 -1
- data/test/lib/facets/core/enumerable/test_probability.rb +1 -1
- data/test/lib/facets/core/enumerable/test_to_h.rb +1 -1
- data/test/lib/facets/core/enumerable/test_uniq_by.rb +1 -1
- data/test/lib/facets/core/file/self/test_create.rb +1 -1
- data/test/lib/facets/core/file/self/test_open_as_string.rb +1 -1
- data/test/lib/facets/core/file/self/test_read_list.rb +1 -1
- data/test/lib/facets/core/file/self/test_sanitize.rb +1 -1
- data/test/lib/facets/core/file/self/test_split_all.rb +1 -1
- data/test/lib/facets/core/float/test_round_at.rb +1 -1
- data/test/lib/facets/core/float/test_round_to.rb +1 -1
- data/test/lib/facets/core/hash/self/test_zipnew.rb +1 -1
- data/test/lib/facets/core/hash/test_alias.rb +1 -1
- data/test/lib/facets/core/hash/test_assert_has_keys.rb +1 -1
- data/test/lib/facets/core/hash/test_assert_has_only_keys.rb +1 -1
- data/test/lib/facets/core/hash/test_at.rb +1 -1
- data/test/lib/facets/core/hash/test_collate.rb +1 -1
- data/test/lib/facets/core/hash/test_each.rb +1 -1
- data/test/lib/facets/core/hash/test_each_with_index.rb +1 -1
- data/test/lib/facets/core/hash/test_each_with_key.rb +1 -1
- data/test/lib/facets/core/hash/test_graph.rb +1 -1
- data/test/lib/facets/core/hash/test_has_keys.rb +1 -1
- data/test/lib/facets/core/hash/test_has_only_keys.rb +1 -1
- data/test/lib/facets/core/hash/test_inverse.rb +1 -1
- data/test/lib/facets/core/hash/test_keys_to_s.rb +1 -1
- data/test/lib/facets/core/hash/test_keys_to_sym.rb +1 -1
- data/test/lib/facets/core/hash/test_op_fetch.rb +1 -1
- data/test/lib/facets/core/hash/test_op_lshift.rb +1 -1
- data/test/lib/facets/core/hash/test_rand_key.rb +1 -1
- data/test/lib/facets/core/hash/test_rand_pair.rb +1 -1
- data/test/lib/facets/core/hash/test_rand_value.rb +1 -1
- data/test/lib/facets/core/hash/test_replace_each.rb +1 -1
- data/test/lib/facets/core/hash/test_shuffle.rb +1 -1
- data/test/lib/facets/core/hash/test_slice.rb +1 -1
- data/test/lib/facets/core/hash/test_swap.rb +1 -1
- data/test/lib/facets/core/hash/test_swapkey.rb +1 -1
- data/test/lib/facets/core/hash/test_to_h.rb +1 -1
- data/test/lib/facets/core/hash/test_to_ostruct.rb +1 -1
- data/test/lib/facets/core/hash/test_to_ostruct_recurse.rb +1 -1
- data/test/lib/facets/core/hash/test_traverse.rb +1 -1
- data/test/lib/facets/core/hash/test_update_each.rb +1 -1
- data/test/lib/facets/core/hash/test_update_keys.rb +1 -1
- data/test/lib/facets/core/hash/test_update_values.rb +1 -1
- data/test/lib/facets/core/hash/test_weave.rb +1 -1
- data/test/lib/facets/core/integer/test_factorial.rb +1 -1
- data/test/lib/facets/core/integer/test_multiple.rb +1 -1
- data/test/lib/facets/core/integer/test_ordinal.rb +1 -1
- data/test/lib/facets/core/integer/test_times_collect.rb +1 -1
- data/test/lib/facets/core/kernel/test___class__.rb +1 -1
- data/test/lib/facets/core/kernel/test_as.rb +1 -1
- data/test/lib/facets/core/kernel/test_assign_from.rb +1 -1
- data/test/lib/facets/core/kernel/test_assign_with.rb +1 -1
- data/test/lib/facets/core/kernel/test_bool.rb +1 -1
- data/test/lib/facets/core/kernel/test_bug.rb +1 -1
- data/test/lib/facets/core/kernel/test_call_stack.rb +1 -1
- data/test/lib/facets/core/kernel/test_called.rb +1 -1
- data/test/lib/facets/core/kernel/test_constant.rb +1 -1
- data/test/lib/facets/core/kernel/test_copy.rb +1 -1
- data/test/lib/facets/core/kernel/test_deep_copy.rb +1 -1
- data/test/lib/facets/core/kernel/test_demo.rb +1 -1
- data/test/lib/facets/core/kernel/test_fn.rb +1 -1
- data/test/lib/facets/core/kernel/test_generate_method_name.rb +1 -1
- data/test/lib/facets/core/kernel/test_get_by_id.rb +1 -1
- data/test/lib/facets/core/kernel/test_here.rb +1 -1
- data/test/lib/facets/core/kernel/test_in.rb +1 -1
- data/test/lib/facets/core/kernel/test_maybe.rb +1 -1
- data/test/lib/facets/core/kernel/test_metaclass.rb +1 -1
- data/test/lib/facets/core/kernel/test_method.rb +1 -1
- data/test/lib/facets/core/kernel/test_methodname.rb +1 -1
- data/test/lib/facets/core/kernel/test_methods.rb +1 -1
- data/test/lib/facets/core/kernel/test_new.rb +1 -1
- data/test/lib/facets/core/kernel/test_object_class.rb +1 -1
- data/test/lib/facets/core/kernel/test_object_hexid.rb +1 -1
- data/test/lib/facets/core/kernel/test_require_all.rb +1 -1
- data/test/lib/facets/core/kernel/test_require_esc.rb +1 -1
- data/test/lib/facets/core/kernel/test_require_facet.rb +1 -1
- data/test/lib/facets/core/kernel/test_resc.rb +1 -1
- data/test/lib/facets/core/kernel/test_returning.rb +1 -1
- data/test/lib/facets/core/kernel/test_send_as.rb +1 -1
- data/test/lib/facets/core/kernel/test_set_from.rb +1 -1
- data/test/lib/facets/core/kernel/test_set_with.rb +1 -1
- data/test/lib/facets/core/kernel/test_silently.rb +1 -1
- data/test/lib/facets/core/kernel/test_singleton.rb +1 -1
- data/test/lib/facets/core/kernel/test_superior.rb +1 -1
- data/test/lib/facets/core/kernel/test_supermethod.rb +1 -1
- data/test/lib/facets/core/kernel/test_this.rb +1 -1
- data/test/lib/facets/core/kernel/test_to_b.rb +1 -1
- data/test/lib/facets/core/kernel/test_to_bool.rb +1 -1
- data/test/lib/facets/core/kernel/test_uri.rb +1 -1
- data/test/lib/facets/core/kernel/test_val.rb +1 -1
- data/test/lib/facets/core/kernel/test_with_accessor.rb +1 -1
- data/test/lib/facets/core/matchdata/test_match.rb +1 -1
- data/test/lib/facets/core/matchdata/test_matchtree.rb +1 -1
- data/test/lib/facets/core/module/test_abstract.rb +1 -1
- data/test/lib/facets/core/module/test_alias_module_function.rb +1 -1
- data/test/lib/facets/core/module/test_ancestor.rb +1 -1
- data/test/lib/facets/core/module/test_basename.rb +1 -1
- data/test/lib/facets/core/module/test_by_name.rb +1 -1
- data/test/lib/facets/core/module/test_clone_using.rb +1 -1
- data/test/lib/facets/core/module/test_dirname.rb +1 -1
- data/test/lib/facets/core/module/test_equate_on.rb +1 -1
- data/test/lib/facets/core/module/test_generate_instance_method_name.rb +1 -1
- data/test/lib/facets/core/module/test_include_as.rb +1 -1
- data/test/lib/facets/core/module/test_inherit.rb +1 -1
- data/test/lib/facets/core/module/test_initializer.rb +1 -1
- data/test/lib/facets/core/module/test_instance_methods.rb +1 -1
- data/test/lib/facets/core/module/test_integrate.rb +1 -1
- data/test/lib/facets/core/module/test_let.rb +1 -1
- data/test/lib/facets/core/module/test_mattr.rb +1 -1
- data/test/lib/facets/core/module/test_memoize.rb +1 -1
- data/test/lib/facets/core/module/test_modspace.rb +1 -1
- data/test/lib/facets/core/module/test_namespace.rb +1 -1
- data/test/lib/facets/core/module/test_nesting.rb +1 -1
- data/test/lib/facets/core/module/test_on_included.rb +1 -1
- data/test/lib/facets/core/module/test_redef.rb +1 -1
- data/test/lib/facets/core/module/test_redefine_method.rb +1 -1
- data/test/lib/facets/core/module/test_redirect.rb +1 -1
- data/test/lib/facets/core/module/test_redirect_method.rb +1 -1
- data/test/lib/facets/core/module/test_remove.rb +1 -1
- data/test/lib/facets/core/module/test_rename.rb +1 -1
- data/test/lib/facets/core/module/test_rename_method.rb +1 -1
- data/test/lib/facets/core/module/test_revisal.rb +1 -1
- data/test/lib/facets/core/module/test_shadow_method.rb +1 -1
- data/test/lib/facets/core/module/test_sort_on.rb +1 -1
- data/test/lib/facets/core/module/test_this.rb +31 -0
- data/test/lib/facets/core/module/test_undef.rb +1 -1
- data/test/lib/facets/core/module/test_wrap.rb +1 -1
- data/test/lib/facets/core/module/test_wrap_method.rb +1 -1
- data/test/lib/facets/core/nilclass/test_blank.rb +1 -1
- data/test/lib/facets/core/nilclass/test_empty.rb +1 -1
- data/test/lib/facets/core/nilclass/test_include.rb +1 -1
- data/test/lib/facets/core/nilclass/test_op_fetch.rb +1 -1
- data/test/lib/facets/core/nilclass/test_size.rb +1 -1
- data/test/lib/facets/core/nilclass/test_to_h.rb +1 -1
- data/test/lib/facets/core/numeric/test_approx.rb +1 -1
- data/test/lib/facets/core/numeric/test_ceil_multiple.rb +1 -1
- data/test/lib/facets/core/numeric/test_succ.rb +1 -1
- data/test/lib/facets/core/numeric/test_to_b.rb +1 -1
- data/test/lib/facets/core/ostruct/test___merge__.rb +1 -1
- data/test/lib/facets/core/ostruct/test___update__.rb +1 -1
- data/test/lib/facets/core/ostruct/test_op_fetch.rb +1 -1
- data/test/lib/facets/core/ostruct/test_op_store.rb +1 -1
- data/test/lib/facets/core/proc/test_compose.rb +1 -1
- data/test/lib/facets/core/proc/test_to_method.rb +1 -1
- data/test/lib/facets/core/range/test_to_r.rb +1 -1
- data/test/lib/facets/core/range/test_to_range.rb +1 -1
- data/test/lib/facets/core/range/test_umbrella.rb +1 -1
- data/test/lib/facets/core/range/test_within.rb +1 -1
- data/test/lib/facets/core/regexp/test_arity.rb +1 -1
- data/test/lib/facets/core/regexp/test_to_re.rb +1 -1
- data/test/lib/facets/core/regexp/test_to_regexp.rb +1 -1
- data/test/lib/facets/core/string/self/test_interpolate.rb +1 -1
- data/test/lib/facets/core/string/self/test_patterns.rb +1 -1
- data/test/lib/facets/core/string/self/test_rand_letter.rb +1 -1
- data/test/lib/facets/core/string/test_align_center.rb +1 -1
- data/test/lib/facets/core/string/test_at_rand.rb +1 -1
- data/test/lib/facets/core/string/test_basename.rb +1 -1
- data/test/lib/facets/core/string/test_blank.rb +1 -1
- data/test/lib/facets/core/string/test_bracket.rb +1 -1
- data/test/lib/facets/core/string/test_camelcase.rb +1 -1
- data/test/lib/facets/core/string/test_camelize.rb +1 -1
- data/test/lib/facets/core/string/test_capitalized.rb +1 -1
- data/test/lib/facets/core/string/test_chars.rb +1 -1
- data/test/lib/facets/core/string/test_cmp.rb +1 -1
- data/test/lib/facets/core/string/test_demodulize.rb +1 -1
- data/test/lib/facets/core/string/test_downcase.rb +1 -1
- data/test/lib/facets/core/string/test_dresner.rb +1 -1
- data/test/lib/facets/core/string/test_each_char.rb +1 -1
- data/test/lib/facets/core/string/test_each_word.rb +1 -1
- data/test/lib/facets/core/string/test_first.rb +1 -1
- data/test/lib/facets/core/string/test_fold.rb +1 -1
- data/test/lib/facets/core/string/test_frequency.rb +1 -1
- data/test/lib/facets/core/string/test_humanize.rb +1 -1
- data/test/lib/facets/core/string/test_indent.rb +1 -1
- data/test/lib/facets/core/string/test_index_all.rb +1 -1
- data/test/lib/facets/core/string/test_last.rb +1 -1
- data/test/lib/facets/core/string/test_line_wrap.rb +1 -1
- data/test/lib/facets/core/string/test_lines.rb +1 -1
- data/test/lib/facets/core/string/test_lowercase.rb +1 -1
- data/test/lib/facets/core/string/test_margin.rb +1 -1
- data/test/lib/facets/core/string/test_methodize.rb +1 -1
- data/test/lib/facets/core/string/test_modulize.rb +1 -1
- data/test/lib/facets/core/string/test_mscan.rb +1 -1
- data/test/lib/facets/core/string/test_natcmp.rb +1 -1
- data/test/lib/facets/core/string/test_nchar.rb +1 -1
- data/test/lib/facets/core/string/test_pathize.rb +1 -1
- data/test/lib/facets/core/string/test_pop.rb +1 -1
- data/test/lib/facets/core/string/test_pot.rb +39 -0
- data/test/lib/facets/core/string/test_probability.rb +1 -1
- data/test/lib/facets/core/string/test_push.rb +1 -1
- data/test/lib/facets/core/string/test_quote.rb +1 -1
- data/test/lib/facets/core/string/test_rand_byte.rb +1 -1
- data/test/lib/facets/core/string/test_rand_index.rb +1 -1
- data/test/lib/facets/core/string/test_range.rb +1 -1
- data/test/lib/facets/core/string/test_range_all.rb +1 -1
- data/test/lib/facets/core/string/test_range_of_line.rb +1 -1
- data/test/lib/facets/core/string/test_regesc.rb +1 -1
- data/test/lib/facets/core/string/test_shatter.rb +1 -1
- data/test/lib/facets/core/string/test_shift.rb +1 -1
- data/test/lib/facets/core/string/test_shuffle.rb +1 -1
- data/test/lib/facets/core/string/test_similarity.rb +1 -1
- data/test/lib/facets/core/string/test_singular.rb +1 -1
- data/test/lib/facets/core/string/test_soundex.rb +1 -1
- data/test/lib/facets/core/string/test_succ.rb +1 -1
- data/test/lib/facets/core/string/test_to_a.rb +1 -1
- data/test/lib/facets/core/string/test_to_b.rb +1 -1
- data/test/lib/facets/core/string/test_to_const.rb +1 -1
- data/test/lib/facets/core/string/test_to_date.rb +1 -1
- data/test/lib/facets/core/string/test_to_proc.rb +1 -1
- data/test/lib/facets/core/string/test_to_re.rb +1 -1
- data/test/lib/facets/core/string/test_to_time.rb +1 -1
- data/test/lib/facets/core/string/test_unix_crypt.rb +1 -1
- data/test/lib/facets/core/string/test_unpack.rb +1 -1
- data/test/lib/facets/core/string/test_unshift.rb +1 -1
- data/test/lib/facets/core/string/test_upcase.rb +1 -1
- data/test/lib/facets/core/string/test_whitespace.rb +1 -1
- data/test/lib/facets/core/string/test_word_filter.rb +1 -1
- data/test/lib/facets/core/string/test_word_wrap.rb +1 -1
- data/test/lib/facets/core/string/test_words.rb +1 -1
- data/test/lib/facets/core/symbol/test_camelcase.rb +1 -1
- data/test/lib/facets/core/symbol/test_camelize.rb +1 -1
- data/test/lib/facets/core/symbol/test_capitalize.rb +1 -1
- data/test/lib/facets/core/symbol/test_capitalized.rb +1 -1
- data/test/lib/facets/core/symbol/test_downcase.rb +1 -1
- data/test/lib/facets/core/symbol/test_not.rb +1 -1
- data/test/lib/facets/core/symbol/test_pad.rb +1 -1
- data/test/lib/facets/core/symbol/test_succ.rb +1 -1
- data/test/lib/facets/core/symbol/test_to_const.rb +1 -1
- data/test/lib/facets/core/symbol/test_to_proc.rb +1 -1
- data/test/lib/facets/core/symbol/test_to_str.rb +1 -1
- data/test/lib/facets/core/symbol/test_underscore.rb +1 -1
- data/test/lib/facets/core/symbol/test_upcase.rb +1 -1
- data/test/lib/facets/core/time/test_change.rb +1 -1
- data/test/lib/facets/core/time/test_elapse.rb +1 -1
- data/test/lib/facets/core/time/test_stamp.rb +1 -1
- data/test/lib/facets/core/time/test_to_date.rb +1 -1
- data/test/lib/facets/core/time/test_to_s.rb +1 -1
- data/test/lib/facets/core/time/test_to_time.rb +1 -1
- data/test/lib/facets/more/test_annotation.rb +1 -1
- data/test/lib/facets/more/test_ansicode.rb +1 -1
- data/test/lib/facets/more/test_association.rb +1 -1
- data/test/lib/facets/more/test_basicobject.rb +1 -1
- data/test/lib/facets/more/test_bbcode.rb +1 -1
- data/test/lib/facets/more/test_bitmask.rb +1 -1
- data/test/lib/facets/more/test_bytes.rb +1 -1
- data/test/lib/facets/more/test_classinherit.rb +1 -1
- data/test/lib/facets/more/test_classmethods.rb +1 -1
- data/test/lib/facets/more/test_coroutine.rb +1 -1
- data/test/lib/facets/more/test_crypt.rb +1 -1
- data/test/lib/facets/more/test_dictionary.rb +1 -1
- data/test/lib/facets/more/test_elementor.rb +1 -1
- data/test/lib/facets/more/test_enumerablepass.rb +1 -1
- data/test/lib/facets/more/test_floatstring.rb +1 -1
- data/test/lib/facets/more/test_functor.rb +1 -1
- data/test/lib/facets/more/test_inheritor.rb +1 -1
- data/test/lib/facets/more/test_interval.rb +1 -1
- data/test/lib/facets/more/test_json.rb +1 -1
- data/test/lib/facets/more/test_lisp.rb +1 -1
- data/test/lib/facets/more/test_lisp_format.rb +1 -1
- data/test/lib/facets/more/test_lrucache.rb +1 -1
- data/test/lib/facets/more/test_mathconstants.rb +1 -1
- data/test/lib/facets/more/test_methodprobe.rb +1 -1
- data/test/lib/facets/more/test_multipliers.rb +1 -1
- data/test/lib/facets/more/test_multiton.rb +1 -1
- data/test/lib/facets/more/test_nackclass.rb +1 -1
- data/test/lib/facets/more/test_nilcomparable.rb +1 -1
- data/test/lib/facets/more/test_openobject.rb +1 -1
- data/test/lib/facets/more/test_overload.rb +1 -1
- data/test/lib/facets/more/test_paramix.rb +1 -1
- data/test/lib/facets/more/test_preinitialize.rb +1 -1
- data/test/lib/facets/more/test_promoteself.rb +1 -1
- data/test/lib/facets/more/test_recorder.rb +1 -1
- data/test/lib/facets/more/test_snapshot.rb +1 -1
- data/test/lib/facets/more/test_statichash.rb +1 -1
- data/test/lib/facets/more/test_syncarray.rb +1 -1
- data/test/lib/facets/more/test_synchash.rb +1 -1
- data/test/lib/facets/more/test_tagiterator.rb +1 -1
- data/test/lib/facets/more/test_timer.rb +1 -1
- data/test/lib/facets/more/test_times.rb +1 -1
- data/test/lib/facets/more/test_tuple.rb +32 -8
- data/test/lib/facets/more/test_typecast.rb +1 -1
- data/test/lib/facets/more/test_uninheritable.rb +1 -1
- data/test/lib/facets/more/test_units.rb +3 -2
- data/test/lib/facets/more/test_xoxo.rb +1 -1
- data/test/lib/facets/more/test_yamlstruct.rb +1 -1
- metadata +15 -10
- data/lib/facet/array/slap.rb +0 -1
- data/lib/facet/module/let.rb +0 -1
- data/lib/facet/string/slap.rb +0 -1
- data/lib/facet/string/to_arr.rb +0 -1
- data/lib/facets/core/string/to_arr.rb +0 -55
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# BuilderFactory
|
|
3
|
+
# Copyright (c) 2006 Thomas Sawyer
|
|
4
|
+
#
|
|
5
|
+
# Ruby License
|
|
6
|
+
#
|
|
7
|
+
#++
|
|
8
|
+
|
|
9
|
+
require 'rexml/document'
|
|
10
|
+
|
|
11
|
+
require 'facets/core/hash/keys_to_s'
|
|
12
|
+
require 'facets/core/kernel/own'
|
|
13
|
+
require 'facets/more/functor' # already requires basicobject
|
|
14
|
+
|
|
15
|
+
# :title: BuilderObject
|
|
16
|
+
#
|
|
17
|
+
# Build structures programatically with Ruby and Ruby's blocks.
|
|
18
|
+
#
|
|
19
|
+
# Builders can use either an implict or explicit receiver.
|
|
20
|
+
# Explicit is the default. To use implicit pass the :implicit
|
|
21
|
+
# option to the constructor.
|
|
22
|
+
#
|
|
23
|
+
# Implict building is more elegant in form, but it is not as
|
|
24
|
+
# functional because it makes it more difficult to refer to
|
|
25
|
+
# external references.
|
|
26
|
+
#
|
|
27
|
+
# BuilderObject avoides metrhod name clashes by using
|
|
28
|
+
# Functor redirection. Unlike other implementations of
|
|
29
|
+
# the Builder patterns which append '!' to builder methods
|
|
30
|
+
# or simply use odd names to avoid clashes, BuilderObject
|
|
31
|
+
# routes all builder method vis the #out method.
|
|
32
|
+
#
|
|
33
|
+
# NOTE The name of this method (#out) may be changed.
|
|
34
|
+
|
|
35
|
+
class BuilderObject < BasicObject
|
|
36
|
+
|
|
37
|
+
# Builder mixin.
|
|
38
|
+
|
|
39
|
+
def self.builder
|
|
40
|
+
@builder ||= Module.new
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def self.builder_include( *mod )
|
|
44
|
+
builder.module_eval { extend *mod }
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
private
|
|
48
|
+
|
|
49
|
+
def builder
|
|
50
|
+
self.__class__.builder
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Prepare builder.
|
|
54
|
+
|
|
55
|
+
def initialize( *options )
|
|
56
|
+
# initialize options
|
|
57
|
+
@options = (Hash === options.last ? options.pop : {} )
|
|
58
|
+
options.each { |o| @options[o] = true }
|
|
59
|
+
# initialize stack
|
|
60
|
+
@stack = []
|
|
61
|
+
# initialize buffer
|
|
62
|
+
@target = builder.new( @options )
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Core of Builder's functionality.
|
|
66
|
+
|
|
67
|
+
def method_missing( tag, *args, &block )
|
|
68
|
+
if @current and block_given?
|
|
69
|
+
@stack << @target
|
|
70
|
+
@target = @current
|
|
71
|
+
if @options[:implicit]
|
|
72
|
+
instance_eval( &block )
|
|
73
|
+
else
|
|
74
|
+
block.call
|
|
75
|
+
end
|
|
76
|
+
@target = @stack.pop
|
|
77
|
+
end
|
|
78
|
+
@target
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Creates object via builder modules,
|
|
82
|
+
# stores as current and appends to buffer.
|
|
83
|
+
|
|
84
|
+
def +( op, *args, &blk )
|
|
85
|
+
obj = builder.send( op, *args, &blk )
|
|
86
|
+
@current = obj
|
|
87
|
+
@target << obj
|
|
88
|
+
self
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
public
|
|
92
|
+
|
|
93
|
+
# raw insert
|
|
94
|
+
|
|
95
|
+
def <<( str )
|
|
96
|
+
r = builder.raw( str )
|
|
97
|
+
if Array === r
|
|
98
|
+
r.each { |e| @target << e }
|
|
99
|
+
else
|
|
100
|
+
@target << r
|
|
101
|
+
end
|
|
102
|
+
self
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# Redirection functor.
|
|
106
|
+
#--
|
|
107
|
+
# TODO Better name?
|
|
108
|
+
#++
|
|
109
|
+
|
|
110
|
+
def out( str=nil )
|
|
111
|
+
if str
|
|
112
|
+
self << str
|
|
113
|
+
else
|
|
114
|
+
@builder_functor ||= Functor.new( &__method__(:+) )
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# text output
|
|
119
|
+
|
|
120
|
+
def to_s
|
|
121
|
+
@target.to_s
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
# Some prebuilt mixin modules for creating builders.
|
|
128
|
+
# These could also be used without builder.
|
|
129
|
+
|
|
130
|
+
module BuilderObject::REXML
|
|
131
|
+
|
|
132
|
+
extend self
|
|
133
|
+
|
|
134
|
+
# Add raw XML markup
|
|
135
|
+
|
|
136
|
+
def raw( str )
|
|
137
|
+
REXML::Document.new( "<root>#{str}</root>" ).root.to_a
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# New REXML document.
|
|
141
|
+
|
|
142
|
+
def document( options={} )
|
|
143
|
+
@options = options
|
|
144
|
+
doc = REXML::Document.new
|
|
145
|
+
# xml declaration
|
|
146
|
+
if options[:version]
|
|
147
|
+
doc << xml(
|
|
148
|
+
options[:version],
|
|
149
|
+
options[:encoding],
|
|
150
|
+
options[:standalone]
|
|
151
|
+
)
|
|
152
|
+
end
|
|
153
|
+
doc
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# Used for initial buffer value in a builder.
|
|
157
|
+
|
|
158
|
+
alias_method :new, :document
|
|
159
|
+
|
|
160
|
+
# XML declaration
|
|
161
|
+
|
|
162
|
+
def xml( version=nil, *args )
|
|
163
|
+
REXML::XMLDecl.new( version=nil, *args )
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def element( tag, *args )
|
|
167
|
+
keys = (Hash === args.last ? args.pop : {})
|
|
168
|
+
e = REXML::Element.new( tag )
|
|
169
|
+
e.add_attributes( keys.keys_to_s )
|
|
170
|
+
e.add_text(args.join(' ')) unless args.empty?
|
|
171
|
+
e
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def instruct( name, *args )
|
|
175
|
+
keys = (Hash === args.last ? args.pop : {})
|
|
176
|
+
content = ( args + keys.collect{ |k,v| %{#{k}="#{v}"} } ).join(' ')
|
|
177
|
+
REXML::Instruction.new( name, content.strip )
|
|
178
|
+
end
|
|
179
|
+
alias_method :instruction, :instruct
|
|
180
|
+
alias_method :pi, :instruct
|
|
181
|
+
|
|
182
|
+
def text( str, *args )
|
|
183
|
+
REXML::Text.new( str, *args )
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
def comment( str, *args )
|
|
187
|
+
REXML::Comment.new( str, *args )
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def cdata( str, *args )
|
|
191
|
+
REXML::CData.new( str, *args )
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
# DTD declarations
|
|
195
|
+
|
|
196
|
+
def doctype!( *args )
|
|
197
|
+
REXML::DocType.new( *args )
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def element!( *args )
|
|
201
|
+
REXML::ElementDecl.new( *args )
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
def attlist!( *args )
|
|
205
|
+
REXML::AttlistDecl.new( *args )
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
def entity!( *args )
|
|
209
|
+
REXML::EntityDecl.new( *args )
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
def notation!( *args )
|
|
213
|
+
REXML::NotationDecl.new( *args )
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
end
|
data/lib/facets/more/functor.rb
CHANGED
|
@@ -14,10 +14,13 @@
|
|
|
14
14
|
# ==========================================================================
|
|
15
15
|
# Revision History
|
|
16
16
|
# ==========================================================================
|
|
17
|
-
#
|
|
17
|
+
# 2006-04-15
|
|
18
|
+
# Code cleanup, changed instance_objects to instance_targets.
|
|
19
|
+
#
|
|
20
|
+
# 2005-09-22 trans
|
|
18
21
|
# Made a subclass of BasicObject.
|
|
19
22
|
#
|
|
20
|
-
#
|
|
23
|
+
# 2005-01-10 trans
|
|
21
24
|
# Ported to Facets.
|
|
22
25
|
# ==========================================================================
|
|
23
26
|
#++
|
|
@@ -33,8 +36,6 @@ require 'facets/more/basicobject'
|
|
|
33
36
|
#
|
|
34
37
|
# == Synopsis
|
|
35
38
|
#
|
|
36
|
-
# require 'mega/functor'
|
|
37
|
-
#
|
|
38
39
|
# f = Functor.new { |op, x| x.send(op, x) }
|
|
39
40
|
# f + 1 #=> 2
|
|
40
41
|
# f + 2 #=> 4
|
|
@@ -50,22 +51,22 @@ require 'facets/more/basicobject'
|
|
|
50
51
|
|
|
51
52
|
class Functor < BasicObject
|
|
52
53
|
|
|
53
|
-
def initialize(*
|
|
54
|
-
@
|
|
55
|
-
@
|
|
54
|
+
def initialize(*targets, &function)
|
|
55
|
+
@targets = targets
|
|
56
|
+
@function = function
|
|
56
57
|
end
|
|
57
58
|
|
|
58
59
|
def method_missing(op, *args, &blk)
|
|
59
60
|
if block_given?
|
|
60
|
-
@
|
|
61
|
+
@function.call(op, *(@targets + args), &blk)
|
|
61
62
|
else
|
|
62
|
-
@
|
|
63
|
+
@function.call(op, *(@targets + args))
|
|
63
64
|
end
|
|
64
65
|
end
|
|
65
66
|
|
|
66
|
-
def
|
|
67
|
-
|
|
68
|
-
end
|
|
67
|
+
def instance_targets ; @targets ; end
|
|
68
|
+
def instance_objects ; @targets ; end # deprecate?
|
|
69
|
+
def instance_function; @function ; end
|
|
69
70
|
|
|
70
71
|
end
|
|
71
72
|
|
data/lib/facets/more/multiton.rb
CHANGED
|
@@ -80,8 +80,8 @@
|
|
|
80
80
|
# A limitation of this approach is that it is impossible to
|
|
81
81
|
# detect if different blocks were given to a contructor (if it takes a
|
|
82
82
|
# block). So it is the constructor arguments _only_ which determine
|
|
83
|
-
# the uniqueness of an object.
|
|
84
|
-
#
|
|
83
|
+
# the uniqueness of an object. To workaround this, define the _class_
|
|
84
|
+
# method ::multiton_id.
|
|
85
85
|
#
|
|
86
86
|
# def Klass.multiton_id(*args, &block)
|
|
87
87
|
# # ...
|
|
@@ -98,13 +98,13 @@
|
|
|
98
98
|
|
|
99
99
|
module Multiton
|
|
100
100
|
|
|
101
|
-
#
|
|
101
|
+
# Pools of objects cached on class type.
|
|
102
102
|
POOLS = {}
|
|
103
103
|
|
|
104
|
-
#
|
|
104
|
+
# Method which can be defined by a class to determine object uniqueness.
|
|
105
105
|
MULTITON_ID_HOOK = :multiton_id
|
|
106
106
|
|
|
107
|
-
#
|
|
107
|
+
# Method which can be defined by a class to create multiton objects.
|
|
108
108
|
MULTITON_NEW_HOOK = :multiton_new
|
|
109
109
|
|
|
110
110
|
def self.append_features( klass )
|
|
@@ -14,6 +14,12 @@
|
|
|
14
14
|
#
|
|
15
15
|
# Console::ProgressBar is a terminal-based progress bar library.
|
|
16
16
|
#
|
|
17
|
+
# == Usage
|
|
18
|
+
#
|
|
19
|
+
# pbar = ConsoleProgressBar.new( "Demo", 100 )
|
|
20
|
+
# 100.times { pbar.inc }
|
|
21
|
+
# pbar.finish
|
|
22
|
+
#
|
|
17
23
|
# == Author(s)
|
|
18
24
|
#
|
|
19
25
|
# * Satoru Takabayashi
|
|
@@ -24,7 +30,7 @@ module Console ; end
|
|
|
24
30
|
|
|
25
31
|
class Console::ProgressBar
|
|
26
32
|
|
|
27
|
-
def initialize
|
|
33
|
+
def initialize(title, total, out = STDERR)
|
|
28
34
|
@title = title
|
|
29
35
|
@total = total
|
|
30
36
|
@out = out
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# XmlBuilder
|
|
3
|
+
# Copyright (c) 2006 Thomas Sawyer
|
|
4
|
+
#
|
|
5
|
+
# Ruby License
|
|
6
|
+
#
|
|
7
|
+
#++
|
|
8
|
+
|
|
9
|
+
require 'rexml/document'
|
|
10
|
+
require 'facets/more/builderobject'
|
|
11
|
+
|
|
12
|
+
# :title: REXMLBuilder
|
|
13
|
+
#
|
|
14
|
+
# Build XML Documents programatically with Ruby and REXML
|
|
15
|
+
# via the Builder Pattern --made possible by Ruby's blocks.
|
|
16
|
+
#
|
|
17
|
+
# XmlBuilder uses REXML to contruct XML documents, helping to ensure
|
|
18
|
+
# XML specification conforamcy.
|
|
19
|
+
#
|
|
20
|
+
# == Usage
|
|
21
|
+
#
|
|
22
|
+
# x = REXMLBuilder.new
|
|
23
|
+
#
|
|
24
|
+
# favs = [ 'cake', 'jelly', 'salt' ]
|
|
25
|
+
#
|
|
26
|
+
# x.table( :width=>'100%' ) {
|
|
27
|
+
# x.tr {
|
|
28
|
+
# favs.each { |v| x.td v }
|
|
29
|
+
# }
|
|
30
|
+
# }
|
|
31
|
+
# }
|
|
32
|
+
#
|
|
33
|
+
# You can also setup the XmlBuilder to assume an implicit self,
|
|
34
|
+
# so the explict reciever is not needed.
|
|
35
|
+
#
|
|
36
|
+
# x = REXMLBuilder.new( :implicit )
|
|
37
|
+
#
|
|
38
|
+
# x.table( :width=>'100%' ) {
|
|
39
|
+
# tr {
|
|
40
|
+
# td "1" ; td "2" ; td "3"
|
|
41
|
+
# }
|
|
42
|
+
# }
|
|
43
|
+
# }
|
|
44
|
+
#
|
|
45
|
+
# Implict building is more elegant in form, but it is not as
|
|
46
|
+
# functional because it makes it more difficult to refer to
|
|
47
|
+
# external values, ie. if 'favs' were used as in the previous
|
|
48
|
+
# example, it would be interpreted as another tag entry, not
|
|
49
|
+
# the array.
|
|
50
|
+
#
|
|
51
|
+
|
|
52
|
+
class REXMLBuilder < BuilderObject
|
|
53
|
+
|
|
54
|
+
builder_include BuilderObject::REXML
|
|
55
|
+
|
|
56
|
+
# Output XML document.
|
|
57
|
+
|
|
58
|
+
def to_s( indent=nil )
|
|
59
|
+
o = ""
|
|
60
|
+
@target.write( o, indent || @options[:indent] || 0 )
|
|
61
|
+
o
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Reroute to output.
|
|
65
|
+
|
|
66
|
+
def method_missing( tag, *args, &block )
|
|
67
|
+
tag = tag.to_s
|
|
68
|
+
if tag[-1,1] == '?'
|
|
69
|
+
raise ArgumentError if block_given?
|
|
70
|
+
out.instruct( tag.chomp('?'), *args )
|
|
71
|
+
elsif tag[-1,1] == '!'
|
|
72
|
+
out.declare( tag.chomp('!'), *args )
|
|
73
|
+
else
|
|
74
|
+
out.element( tag, *args )
|
|
75
|
+
end
|
|
76
|
+
super
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
# TODO
|
|
84
|
+
|
|
85
|
+
#=begin
|
|
86
|
+
|
|
87
|
+
x = REXMLBuilder.new( :version => '1.0' )
|
|
88
|
+
|
|
89
|
+
x.html {
|
|
90
|
+
x.head { x.title "Test Document" }
|
|
91
|
+
x.body( "try me" ){
|
|
92
|
+
x.out.text "No more!"
|
|
93
|
+
x.r? "x"
|
|
94
|
+
x.img :src=>"smile.jp"
|
|
95
|
+
x.h1 "Try Me"
|
|
96
|
+
x.h2 "This is a test."
|
|
97
|
+
x.div { x.span "Try" }
|
|
98
|
+
x.out "<jump>one</jump>"
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
puts x
|
|
103
|
+
|
|
104
|
+
#=end
|
data/lib/facets/more/tuple.rb
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
#--
|
|
2
2
|
# Tuple
|
|
3
|
-
#
|
|
4
3
|
# Copyright (c) 2005 Thomas Sawyer
|
|
5
4
|
#
|
|
6
5
|
# Ruby License
|
|
@@ -16,6 +15,10 @@
|
|
|
16
15
|
# Revision History:
|
|
17
16
|
# ==========================================================================
|
|
18
17
|
#
|
|
18
|
+
# 2006-04-10 trans
|
|
19
|
+
# Made thread safe (I hope) by using Multiton; No longer subclass
|
|
20
|
+
# of Array; and improved generally.
|
|
21
|
+
#
|
|
19
22
|
# 2005-11-16 trans
|
|
20
23
|
# Improved comparison operators to convert non-tuple parameters
|
|
21
24
|
# into Tuples.
|
|
@@ -29,16 +32,22 @@
|
|
|
29
32
|
#
|
|
30
33
|
# ==========================================================================
|
|
31
34
|
#
|
|
32
|
-
#
|
|
35
|
+
# TODO The #hash method needs a touch-up.
|
|
36
|
+
#
|
|
37
|
+
# TODO There are a few more methods yet to borrow from Array.
|
|
38
|
+
# Consider how #+, #-, etc. ought to work.
|
|
33
39
|
#
|
|
34
40
|
#++
|
|
35
41
|
|
|
42
|
+
require 'facets/more/multiton'
|
|
43
|
+
|
|
36
44
|
#:title: Tuple
|
|
37
45
|
#
|
|
38
|
-
#
|
|
39
|
-
#
|
|
40
|
-
# using
|
|
41
|
-
#
|
|
46
|
+
# Tuple is essentially an Array, but Comaparable and Immutable.
|
|
47
|
+
#
|
|
48
|
+
# A tuple can be made using #new or #[] just as one builds an array,
|
|
49
|
+
# or using the #to_t method on a string or array. With a string tuple
|
|
50
|
+
# remembers the first non-alphanumeric character as the tuple divider.
|
|
42
51
|
#
|
|
43
52
|
# == Usage
|
|
44
53
|
#
|
|
@@ -48,30 +57,128 @@
|
|
|
48
57
|
# t1 < t2 #=> true
|
|
49
58
|
# t1 > t2 #=> false
|
|
50
59
|
#
|
|
51
|
-
# t1 =
|
|
52
|
-
# t2 =
|
|
60
|
+
# t1 = '1.2.3'.to_t
|
|
61
|
+
# t2 = '1-2-3'.to_t
|
|
62
|
+
#
|
|
63
|
+
# puts t1 #=> 1.2.3
|
|
64
|
+
# puts t2 #=> 1-2-3
|
|
53
65
|
#
|
|
54
66
|
# t1 == t2 #=> true
|
|
55
67
|
#
|
|
68
|
+
# Keep in mind that Tuple[1,2,3] is not the same as Tuple['1','2','3'].
|
|
69
|
+
#
|
|
56
70
|
# == Author(s)
|
|
57
71
|
#
|
|
58
72
|
# * Thomas Sawyer
|
|
59
73
|
#
|
|
60
74
|
|
|
61
|
-
class ::Tuple
|
|
75
|
+
class ::Tuple
|
|
62
76
|
|
|
77
|
+
include ::Multiton
|
|
78
|
+
include ::Enumerable
|
|
63
79
|
include ::Comparable
|
|
64
80
|
|
|
65
|
-
def
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
81
|
+
def self.multiton_id(arg=0, default=0, &block)
|
|
82
|
+
if block_given?
|
|
83
|
+
values = []
|
|
84
|
+
arg.times { |i| values << block[i] }
|
|
85
|
+
elseif Integer === arg
|
|
86
|
+
values = [ default ] * arg
|
|
87
|
+
else
|
|
88
|
+
values = arg.to_ary
|
|
89
|
+
end
|
|
90
|
+
values
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def initialize(arg=0, default=0, &blk)
|
|
94
|
+
if block_given?
|
|
95
|
+
@values = []
|
|
96
|
+
arg.times { |i| @values << blk[i] }
|
|
97
|
+
elseif Integer === arg
|
|
98
|
+
@values = [ default ] * arg
|
|
99
|
+
else
|
|
100
|
+
@values = arg.to_ary
|
|
101
|
+
end
|
|
102
|
+
@default = default
|
|
103
|
+
@divider = '.'
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
attr_accessor :default, :divider
|
|
107
|
+
|
|
108
|
+
protected
|
|
109
|
+
|
|
110
|
+
def values() @values end
|
|
111
|
+
|
|
112
|
+
public
|
|
113
|
+
|
|
114
|
+
def inspect() to_a.inspect end
|
|
115
|
+
|
|
116
|
+
def to_t() self end
|
|
117
|
+
def to_tuple() self end
|
|
118
|
+
|
|
119
|
+
def to_a() Array(@values) end
|
|
120
|
+
def to_ary() Array(@values) end
|
|
121
|
+
|
|
122
|
+
def to_s( divider=nil )
|
|
123
|
+
@values.join(divider||@divider)
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def size() @values.size end
|
|
127
|
+
def length() @values.size end
|
|
128
|
+
|
|
129
|
+
def empty?()
|
|
130
|
+
return true if @values.empty?
|
|
131
|
+
return true if @values == [ @default ] * @values.size
|
|
132
|
+
false
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def each( &block )
|
|
136
|
+
@values.each( &block )
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def each_index( &block )
|
|
140
|
+
@values.each_index( &block )
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def [](i)
|
|
144
|
+
@values.fetch(i,@default)
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def []=(i,v)
|
|
148
|
+
@values[i] = v
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def index() @values.index end
|
|
152
|
+
def rindex() @values.rindex end
|
|
153
|
+
|
|
154
|
+
# Unlike Array, Tuple#<< cannot act in place
|
|
155
|
+
# becuase Tuple's are immutable.
|
|
156
|
+
def <<( obj )
|
|
157
|
+
self.class.new( to_a << obj )
|
|
69
158
|
end
|
|
70
159
|
|
|
71
|
-
def
|
|
160
|
+
def pop() Tuple.new( to_a.pop ) end
|
|
161
|
+
def push( obj ) Tuple.new( to_a.push(obj) ) end
|
|
162
|
+
def pull() Tuple.new( to_a.shift ) end
|
|
163
|
+
def pot( obj ) Tuple.new( to_a.unshift(obj) ) end
|
|
164
|
+
alias_method :unshift, :pot
|
|
165
|
+
alias_method :shift, :pull
|
|
166
|
+
|
|
167
|
+
# Returns true if two tuple references are for the
|
|
168
|
+
# very same tuple.
|
|
169
|
+
def eql?( other )
|
|
170
|
+
return true if object_id == other.object_id
|
|
171
|
+
#return true if values.eql? other.values
|
|
172
|
+
end
|
|
72
173
|
|
|
73
|
-
def
|
|
74
|
-
|
|
174
|
+
def <=>( other )
|
|
175
|
+
other = other.to_t
|
|
176
|
+
[size, other.size].max.times do |i|
|
|
177
|
+
c = self[i] <=> other[i]
|
|
178
|
+
return c if c != 0
|
|
179
|
+
end
|
|
180
|
+
0
|
|
181
|
+
end
|
|
75
182
|
|
|
76
183
|
# For pessimistic constraint (like '~>' in gems)
|
|
77
184
|
def =~( other )
|
|
@@ -81,60 +188,93 @@ class ::Tuple < ::Array
|
|
|
81
188
|
self >= other and self < upver
|
|
82
189
|
end
|
|
83
190
|
|
|
84
|
-
def
|
|
85
|
-
def
|
|
86
|
-
def <( other ) ; super( other.to_t ) ; end
|
|
87
|
-
def >=( other ) ; super( other.to_t ) ; end
|
|
88
|
-
def <=( other ) ; super( other.to_t ) ; end
|
|
191
|
+
def first() @values.first end
|
|
192
|
+
def last() @values.last end
|
|
89
193
|
|
|
90
|
-
#
|
|
194
|
+
# These are useful for using a Tuple as a version.
|
|
195
|
+
def major() @values.first end
|
|
196
|
+
def minor() @values.at(1) end
|
|
197
|
+
def teeny() @values.at(2) end
|
|
198
|
+
|
|
199
|
+
# Unique hash value.
|
|
200
|
+
def hash
|
|
201
|
+
# TODO This needs to take into account the default
|
|
202
|
+
# and maybe the divider too.
|
|
203
|
+
to_a.hash
|
|
204
|
+
end
|
|
91
205
|
|
|
92
|
-
|
|
206
|
+
# class-level -----------------------------------------------
|
|
93
207
|
|
|
94
208
|
class << self
|
|
95
209
|
|
|
96
|
-
|
|
210
|
+
def []( *args )
|
|
211
|
+
new( args )
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
#
|
|
97
215
|
|
|
98
|
-
def
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
div = /\W/.match(arg)[0]
|
|
104
|
-
args = arg.to_s.split(/\W/).collect { |e| e.to_i }
|
|
216
|
+
def cast_from_string( str ) # :yield:
|
|
217
|
+
args = str.to_s.split(/\W/)
|
|
218
|
+
div = /\W/.match( str.to_s )[0]
|
|
219
|
+
if block_given?
|
|
220
|
+
args = args.collect{ |a| yld[a] }
|
|
105
221
|
end
|
|
106
|
-
|
|
222
|
+
t = self.new( args )
|
|
223
|
+
t.divider = div
|
|
224
|
+
t
|
|
107
225
|
end
|
|
108
226
|
|
|
109
|
-
def
|
|
110
|
-
|
|
227
|
+
def cast_from_array( arr )
|
|
228
|
+
self.new( arr )
|
|
111
229
|
end
|
|
112
230
|
|
|
113
|
-
# Parses a constraint returning the operation
|
|
114
|
-
|
|
115
|
-
def
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
231
|
+
# Parses a constraint returning the operation as a lambda.
|
|
232
|
+
|
|
233
|
+
def parse_constraint( constraint )
|
|
234
|
+
constraint = constraint.strip
|
|
235
|
+
re = %r{^(=~|~>|<=|>=|==|=|<|>)?(\d+(:?[-.]\d+)*)$}
|
|
236
|
+
if md = re.match( constraint )
|
|
237
|
+
if op = md[1]
|
|
238
|
+
op = '=~' if op == '~>'
|
|
239
|
+
op = '==' if op == '='
|
|
240
|
+
val = new( md[2] )
|
|
241
|
+
else
|
|
242
|
+
op = '=='
|
|
243
|
+
val = new( constraint )
|
|
244
|
+
end
|
|
121
245
|
else
|
|
122
|
-
|
|
123
|
-
val = instance(constraint.strip)
|
|
246
|
+
raise ArgumentError, "invalid constraint"
|
|
124
247
|
end
|
|
125
|
-
return
|
|
248
|
+
return op, val
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
def constraint_to_lambda( constraint )
|
|
252
|
+
op, val = *parse_constraint( constraint )
|
|
253
|
+
lambda { |t| t.send(op, val) }
|
|
126
254
|
end
|
|
127
255
|
|
|
128
|
-
end
|
|
256
|
+
end
|
|
129
257
|
|
|
130
258
|
end
|
|
131
259
|
|
|
260
|
+
|
|
132
261
|
# Conveniently turn a string into a tuple.
|
|
133
262
|
|
|
134
263
|
class ::String
|
|
135
264
|
|
|
265
|
+
def to_t( &yld )
|
|
266
|
+
Tuple.cast_from_string( self, &yld )
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
# Convert and array into a tuple.
|
|
273
|
+
|
|
274
|
+
class ::Array
|
|
275
|
+
|
|
136
276
|
def to_t
|
|
137
|
-
|
|
277
|
+
Tuple.cast_from_array( self )
|
|
138
278
|
end
|
|
139
279
|
|
|
140
280
|
end
|
|
@@ -148,20 +288,44 @@ end
|
|
|
148
288
|
# |_|\___||___/\__|
|
|
149
289
|
#
|
|
150
290
|
|
|
151
|
-
=begin
|
|
291
|
+
=begin testing
|
|
152
292
|
|
|
153
293
|
require 'test/unit'
|
|
154
294
|
|
|
155
|
-
class TC_Tuple < Test::Unit::TestCase
|
|
295
|
+
class TC_Tuple < Test::Unit::TestCase
|
|
296
|
+
|
|
297
|
+
def test_01
|
|
298
|
+
t1 = Tuple[1,2,3]
|
|
299
|
+
t2 = Tuple[2,4,5]
|
|
300
|
+
assert( t1 < t2 )
|
|
301
|
+
assert( t2 > t1 )
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
def test_02
|
|
305
|
+
t1 = Tuple[1,2,3]
|
|
306
|
+
a1 = t1.to_a
|
|
307
|
+
assert( Array === a1 )
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
def test_03
|
|
311
|
+
t1 = Tuple[1,2,3]
|
|
312
|
+
t2 = Tuple[1,2,3]
|
|
313
|
+
assert( t1.object_id === t2.object_id )
|
|
314
|
+
end
|
|
156
315
|
|
|
157
|
-
def
|
|
158
|
-
|
|
159
|
-
|
|
316
|
+
def test_04
|
|
317
|
+
t1 = Tuple[1,2,3]
|
|
318
|
+
t1 = t1 << 4
|
|
319
|
+
assert( Tuple === t1 )
|
|
320
|
+
t2 = Tuple[1,2,3,4]
|
|
321
|
+
assert( t1.object_id == t2.object_id )
|
|
160
322
|
end
|
|
161
323
|
|
|
162
|
-
def
|
|
163
|
-
|
|
164
|
-
assert(
|
|
324
|
+
def test_05
|
|
325
|
+
t1 = "1.2.3".to_t
|
|
326
|
+
assert( Tuple === t1 )
|
|
327
|
+
t2 = Tuple['1','2','3']
|
|
328
|
+
assert( t1.object_id == t2.object_id )
|
|
165
329
|
end
|
|
166
330
|
|
|
167
331
|
end
|