Issue #6684 has been updated by nobu (Nobuyoshi Nakada).


=begin
(({something.do do end})) seems messy a little.

(({something.do do end}))?????????????????????
=end

----------------------------------------
Feature #6684: Object#do
https://bugs.ruby-lang.org/issues/6684#change-27786

Author: merborne (kyo endo)
Status: Open
Priority: Normal
Assignee: 
Category: 
Target version: 


=begin
#Object#do
This is my first post.

???????????稿??????????????????????????????????

Let me propose a new method `Object#do`.

次??????????????`Object#do`?????????????????

    class Object
      def do(*args, &blk)
        yield(self, *args)
      end
    end

`do` encapsulate a sequencial procedure into a block. It makes some temporal variables to be block local and enhance code readability. I might say that `do` is an Object#tap with block result, or is Array#map for one item.

`do`?????????????対??????????????????????????????????込???????????????????????????????????????????????????????????????媭??????????????????????????????Object#tap????????????Array#map?????????????????????????

##Usage

    # calculate average and standard deviation for list
    #
    # without `do`
    scores = [56, 87, 49, 75, 90, 63, 65]
    scores.inject(:+) / scores.size # => 69
    
    avg = scores.inject(:+) / scores.size
    sigmas = scores.map { |n| (avg - n)**2 }
    sd = Math.sqrt(sigmas.inject(:+) / scores.size) # => 14.247806848775006
    
    # with `do`
    avg = [56, 87, 49, 75, 90, 63, 65].do { |s| s.inject(:+) / s.size } # => 69
    
    sd = scores.do { |s|
      avg = s.inject(:+) / s.size
      sigmas = s.map { |n| (avg - n)**2 }
      Math.sqrt(sigmas.inject(:+) / s.size)
    }
    sd # => 14.247806848775006
    
    # create a hash from a set of lists
    #
    # without `do`
    h = Hash[ [:a, :b, :c].zip([1, 2, 3]) ] # => {:a=>1, :b=>2, :c=>3}
    
    # with `do`
    h = [:a, :b, :c].zip([1,2,3]).do { |arr| Hash[arr] } # => {:a=>1, :b=>2, :c=>3}
    
    
    # sum of array using recursion
    #
    # without `do`
    def sum(lst, mem=0)
      return mem if lst.empty?
      sum(lst.drop(1), mem+lst.first)
    end
    
    sum [*1..5], 5 # => 20
    
          # or
    
    def sum(lst, mem=0)
      return mem if lst.empty?
      fst, *tail = lst
      sum(tail, mem+fst)
    end
    
    # with `do`
    def sum(lst, mem=0)
      return mem if lst.empty?
      lst.do { |fst, *tail| sum(tail, mem+fst) }
    end
    
    sum2 [*1..5], 5 # => 20

BasicObject#instance_eval works for the above, but it not appropriate for them.

????????????BasicObject#instance_eval????????????????????????種??????????????????????????????????


Thank you for your consideration.
=end


-- 
http://bugs.ruby-lang.org/