From: "merborne (kyo endo)" Date: 2012-07-02T22:39:00+09:00 Subject: [ruby-core:46105] [ruby-trunk - Feature #6687][Open] Enumerable#with Issue #6687 has been reported by merborne (kyo endo). ---------------------------------------- Feature #6687: Enumerable#with https://bugs.ruby-lang.org/issues/6687 Author: merborne (kyo endo) Status: Open Priority: Normal Assignee: Category: Target version: =begin Let me propose `Enumerable#with` for an alias of `Enumerable#each_with_object` or replace of it. `Enumerable#each_with_object`������������������������������������������������������������`Enumerable#with`��������������������� ##Reason ##������ When you create a hash using `Enumerable#inject`, you should ensure that the block return the hash. `Enumerable#inject`��������������������������������������������������������������������������������������������������������������������������������������������������������� words.inject(Hash.new(0)) { |h, word| h[word] += 1; h } # => {"You"=>3, "say"=>10, "Yes"=>1, "I"=>7, "No"=>1, "Stop"=>1, "and"=>2, "Go"=>1, "go"=>2, "Oh"=>1, "no"=>1, "Goodbye"=>2, "Hello"=>2, "hello"=>5, "don"=>2, "t"=>2, "know"=>2, "why"=>2, "you"=>2, "goodbye"=>1} Many rubyists, however, hate this, and there are many discussions for it. ���������������������������Rubyist��������������������������������������������������������������������������������������������� Feature #5662: inject-accumulate, or Haskell's mapAccum* - ruby-trunk - Ruby Issue Tracking System http://bugs.ruby-lang.org/issues/5662 Ruby inject with intial being a hash - Stack Overflow http://stackoverflow.com/questions/9434162/ruby-inject-with-intial-being-a-hash `Enumerable#each_with_object` is often presented for one of the best solutions for it. ���������������������������������������������Enumerable#each_with_object��������������������������������� words.each_with_object(Hash.new(0)) { |word, h| h[word] += 1 } # => {"You"=>3, "say"=>10, "Yes"=>1, "I"=>7, "No"=>1, "Stop"=>1, "and"=>2, "Go"=>1, "go"=>2, "Oh"=>1, "no"=>1, "Goodbye"=>2, "Hello"=>2, "hello"=>5, "don"=>2, "t"=>2, "know"=>2, "why"=>2, "you"=>2, "goodbye"=>1} However, `each_with_object` is still unfamiliar and then not used frequently. The biggest reason, I think, is its lengthy name. ������������������������������������������������������������each_with_object��������������������������������������������������������������������������������������������������������������������������������������������� `each_with_object` is the 39th longest-name method among 754 at Ruby 1.9.3, based on following calculation; ���������������������������Ruby1.9.3���������������each_with_object������754������39��������������������������������������������������������������������������� methods = Module.constants.flat_map do |c| next [] if c == :Gem k = Module.const_get(c) k.methods(false) + k.instance_methods(false) rescue [] end.uniq.reject { |m| "#{m}".start_with? '_deprecated' }.sort_by { |m| -m.size } methods.size # => 754 methods.index(:each_with_object) # => 39 puts methods.take(100).group_by(&:size).to_a The output is here. ��������������� 26 protected_instance_methods instance_variable_defined? 25 protected_method_defined? 24 private_instance_methods 23 class_variable_defined? public_instance_methods define_singleton_method private_method_defined? 22 singleton_method_added public_instance_method public_method_defined? 21 instance_variable_get instance_variable_set remove_class_variable 20 private_class_method repeated_combination repeated_permutation compare_by_identity? 19 respond_to_missing? abort_on_exception= public_class_method compare_by_identity 18 undefine_finalizer instance_variables abort_on_exception class_variable_get class_variable_set relative_path_from 17 internal_encoding external_encoding default_internal= default_external= protected_methods singleton_methods ascii_compatible? 16 global_variables executable_real? initialize_clone each_with_object # <= Here! require_relative private_constant default_external included_modules instance_methods define_finalizer default_internal 15 private_methods fixed_encoding? class_variables instance_method each_with_index public_constant garbage_collect source_location valid_encoding? singleton_class world_writable? local_variables world_readable? method_defined? 14 readable_real? locale_charmap const_defined? collect_concat initialize_dup add_trace_func close_on_exec= close_on_exec? named_captures set_trace_func write_nonblock writable_real? each_codepoint force_encoding public_methods 13 const_missing each_filename default_proc= set_backtrace public_method read_nonblock instance_exec absolute_path count_objects instance_eval 12 marshal_load reverse_each exclude_end? instance_of? make_symlink set_encoding block_given? default_proc slice_before marshal_dump 11 rationalize realdirpath each_object expand_path with_object This result shows that methods which has 15+ name length is mostly for reflection or for special purpose. `each_with_object` is a general purpose method, the name should be shorter. ������������������������������������������������15������������������������������������������������������������������������������������������������������������������������������each_with_object��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� I propose Enumerable#with for it. a word `object` in `each_with_object` is obvious and not necessary to spcify the purpose, because all data in Ruby is `object`. Also, a word `each` in `each_with_object` is not essential, then omittable in view of the fact that it is called to Enumerable object. I think that a word `with` still works for describing the same of `each_with_object`. ���������Enumerable#with������������������������������Ruby���������������������������������������������������������������������each_with_object������������object���������������������������������������������������Enumerable���������������������������������������������������������������������������������each������������������������������������������������������������������������������������with������������������������������������Enumerable��������������������������������������������������������������������������������������������������������� Lastly, following is examples with `Enumerable#with` ������������`Enumerable#with`��������������������������������� Enumerable.send(:alias_method, :with, :each_with_object) words.with(Hash.new(0)) { | word, h| h[word] += 1 } # => {"You"=>3, "say"=>10, "Yes"=>1, "I"=>7, "No"=>1, "Stop"=>1, "and"=>2, "Go"=>1, "go"=>2, "Oh"=>1, "no"=>1, "Goodbye"=>2, "Hello"=>2, "hello"=>5, "don"=>2, "t"=>2, "know"=>2, "why"=>2, "you"=>2, "goodbye"=>1} [*1..10].with(5).map(&:*) # => [5, 10, 15, 20, 25, 30, 35, 40, 45, 50] ['ruby', 'python', 'haskell'].with('ist').map(&:+) # => ["rubyist", "pythonist", "haskellist"] Thank you for your consideration. ��������������������������������������������������� =end -- http://bugs.ruby-lang.org/