From: "merborne (kyo endo)" Date: 2012-07-04T21:09:17+09:00 Subject: [ruby-core:46178] [ruby-trunk - Feature #6687] Enumerable#with Issue #6687 has been updated by merborne (kyo endo). knu (Akinori MUSHA) wrote: > I doubt it. Enumerable is often just one probably minor aspect of an including class, and even when used with an array or hash it is not obvious from the name with or with_object that it would iterate over the contents. I'd say it's too bold. Without a block, `each_with_object` does not start iteration to the elements, just returns a Enumerator object. Operation to the elements is passed to next method. [10,20,30].each_with_object(3).max_by { |i, o| i%o } # => [20, 3] ['ruby', 'python', 'haskell'].each_with_object('ist').map(&:+) # => ["rubyist", "pythonist", "haskellist"] In this example, `each_with_object` only bind a passed object to each element. So I feel a word `each` is less appropriate for this, only `with` is more appropriate. [10,20,30].with(3).max_by { |i, o| i%o } # => [20, 3] ['ruby', 'python', 'haskell'].with('ist').map(&:+) # => ["rubyist", "pythonist", "haskellist"] When `each_with_object` takes a block, the iteration start. so I agree that the meaning is less clearer without a word `each` in this case. However, let me think about Array#each or Hash#each. Thease `each` methods, when they takes a block, return `self`, not block result. From this, I expect a method that have a word `each` returns `self`. or makes irregular iterations like `each_cons`, `each_slice`. As long as it is used to enumerable object, with a block, I think a word `with` still works same as `each_with_object`. > P.S. > You may want to search for a past discussion: > http://blade.nagaokaut.ac.jp/cgi-bin/vframe.rb/ruby/ruby-core/17084?16896-17624 This is very helpful for me. thank you. ---------------------------------------- Feature #6687: Enumerable#with https://bugs.ruby-lang.org/issues/6687#change-27800 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/