Issue #6687 has been updated by merborne (kyo endo).


nobu (Nobuyoshi Nakada) wrote:
> I don't think "with" is nice as a method name.
> What does it `with' the argument?
> "each" should not be omitted, I guess.

It iterate(or enumerate) with the argument. The receiver, by itself tells it, I think.
I think #each tells nothing. it suggests the returning value is `self` instead.
This method returns a passed object...

How about #return_with ?

----------------------------------------
Feature #6687: Enumerable#with
https://bugs.ruby-lang.org/issues/6687#change-28453

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/