Что такое анонимные функции?

В моем путешествии по тысячам строк Ruby мне очень сложно с концепцией анонимных функций. Wikipedia говорит что-то о, в которой есть какая-то безымянная душа в коде, и она подчиняется более высокому порядку, но мое понимание заканчивается на этом.

Или, другими словами, как я (когда я это понимаю) объясню анонимные функции моей маме?

Ответы

Ответ 1

Анонимная функция имеет следующие характеристики:

  • У него нет имени (следовательно, анонимного)
  • Определяется встроенным
  • Используется, когда вам не нужны служебные/формальные функции нормальной функции
  • Явным образом не упоминается более одного раза, если не передано в качестве аргумента другой функции

Ответ 2

Вот один пример анонимной функции в Ruby (называемый в данном случае блоком):

my_array.each{ |item| puts item }

Где анонимная функция в приведенном выше? Почему, тот, который получает единственный параметр, называет его "item", а затем печатает его. В JavaScript вышеуказанное может быть написано как...

Array.prototype.each = function(anon){
  for (var i=0,len=this.length;i<len;++i) anon(this[i]);
};
myArray.each(function(item){ console.log(item); });

..., который делает несколько более понятным, что функция передается как аргумент, а также помогает оценить синтаксис Ruby.:)

Здесь другая анонимная функция (назад в Ruby):

def count_to(n)
  puts "I'm going to count to #{n}"
  count = lambda do |i|
    if (i>0)
      count[i-1]
      puts i
    end
  end
  count[n]
  puts "I'm done counting!"
end
count_to(3)
#=> I'm going to count to 3
#=> 1
#=> 2
#=> 3
#=> I'm done counting!

Хотя этот пример явно надуман, он показывает, как вы можете создать новую функцию (в этом случае с именем count) и назначить ее переменной, и использовать ее для рекурсивных вызовов внутри основного метода. (Некоторые считают, что это лучше, чем создание второго метода только для рекурсии или повторного использования главного метода для рекурсии с очень разными параметрами.)

Функция не имеет имени, переменная делает. Вы можете назначить его любому числу переменных, все с разными именами.

Возвращаясь к первому примеру, существует даже синтаксис в Ruby для передачи лямбда в качестве единственного, благословенного блока:

print_it = lambda{ |item| puts item }
%w[a b c].each(&print_it)
#=> a
#=> b
#=> c

... но вы также можете передать лямбду в качестве нормального параметра и вызвать ее позже, как показано здесь:

module Enumerable
  def do_both_to_each( f1, f2 )
    each do |item|
      f1[item]
      f2[item]
    end
  end
end

print_prefix  = lambda{ |i| print "#{i}*#{i} -> " }
print_squared = lambda{ |i| puts i*i }

(1..4).do_both_to_each(print_prefix,print_squared)
#=> 1*1 -> 1
#=> 2*2 -> 4
#=> 3*3 -> 9
#=> 4*4 -> 16

Ответ 3

В зависимости от предыдущих ответов анонимные функции очень полезны, когда вы работаете с закрывает:

def make_adder n
  lambda { |x|
    x + n
  }
end

t = make_adder 100
puts t.call 1

Или (в Ruby 1.9):

def make_adder_1_9 n
   ->(x) {
     x + n
   }
end

t_1_9 = make_adder_1_9 100
puts t_1_9.call 1

Ответ 4

Так же, как Wikipedia говорит: функция без имени.

Это означает, что вы не можете вызвать функцию обычным способом, используя ее имя и параметры. Скорее, сама функция обычно является параметром для другой функции. Функция, которая работает с функциями, называется "функцией более высокого порядка".

Рассмотрим этот JavaScript (я знаю, что вы отметили этот рубин, но...):

  window.onload=function(){
           //some code here
  }

Функция будет выполняться при загрузке страницы, но вы не можете ее вызывать по имени, потому что у нее нет имени.