I am learning Ruby and I do not quite understand what: * means in injection (: *)

I am writing a method for calculating the factorial of a number, and in my search I have found something similar to this.

def factorial(number)
  (1..number).inject(:*) || 1
end

This works, and I understand what the injection function does, but I don't understand what the part means (:\*).

I know that this should be a short version of the letter {|num, prod| num*prod}, but I would like a clear explanation. Thank!!

+4
source share
4 answers

:*is simply the name of the method for the *method injectto execute. If you look at the documentation for inject http://ruby-doc.org/core-2.2.2/Enumerable.html#method-i-inject

It states that

, memo. . memo .

, inject { |memo, obj| block }

ary = [1,2,3]
ary.inject(:*)
#=> 6
ary.inject { |memo, obj| memo.*(obj) }
#=> 6
+2

:* - . - . :* "*", , .

ruby ​​ . .*(second) . , 3.*(4) 3*4. 3*4 .

ruby ​​ public_send . 3.public_send(:*, 4) , 3*4.

public_senT, .

[ 1, 2, 3, 4 ].inject(:*)

'*' , inject :

[ 1, 2, 3, 4 ].inject(:*) == 1 * 2 * 3 * 4

, 1 * 2 * 3 * 4 : * , , .

module Enumerable
  def inject_asterisk
     tally = first
     rest = slice(1, length - 1)
     rest.each  do |next_num|
       tally = tally * next_num
     end
     return tally
  end
end
[2, 3, 5].inject_asterisk #=> 30

, , tally next_number, tally . ruby ​​ , .

module Enumerable
  def inject_block(&block)
     tally = first
     rest = slice(1, length - 1)
     rest.each  do |next_num|
       tally = block.call(tally, next_num)
     end
     return tally
  end
end
[2, 3, 5].inject_block {|tally, next_num| tally + next_num } #=> 10

{|tally, next_num| tally.method_of_tally(next_num) }

( tally + next_num < == > tally.+(next_num) < == > tally.public_send(:+,next_num), :method_of_tally .

 module Enumerable
  def my_inject(method_of_tally_symbol, &block)

     if method_of_tally_symbol
        block = Proc.new  { |tally, next_num| 
               tally.public_send(method_of_tally_symbol, next_num) 
               }
     end

     tally = first
     rest = slice(1, length - 1)
     rest.each  do |next_num|
       tally = block.call(tally, next_num)
     end
     return tally
  end
end
[2, 3, 5].my_inject(:+) #=> 10

, .

+2

symbol to proc . -

array.map { |e| e.join }

proc,

array.map(&:join)

inject reduce , &

, , numbers

,

numbers.inject(&:+) 

numbers.inject(:+)
0

http://ruby-doc.org/core-2.2.2/Enumerable.html#method-i-inject

Inject is an enumerated type method that combines the elements of a specified enumerated using a character (as in your case) or a block (as in the length you proposed).

For instance:

(5..10).reduce(:*) equivalently (5..10).inject { |prod, n| prod + n }

0
source

Source: https://habr.com/ru/post/1589055/


All Articles