Перешёл с C#: блоки...
 
Уведомления
Очистить всё

Перешёл с C#: блоки, yield, proc и lambda. Объясните на пальцах

5 Сообщения
4 Пользователи
1 Реакции
455 Просмотры
slava52
Сообщения: 9
Автор темы
Разобрался с блоками middle-разработчик
Присоединился: 2 года назад
[#48]

Месяц на Rails 7.2 после шести лет на C#. Делегаты и LINQ я понимаю, а в Ruby путаюсь: блок, yield, &block, proc, lambda и ещё ->. Что из этого встречается в обычном коде каждый день, а что пока можно не знать? Ruby 3.3.


4 ответа
kirill_spb
Сообщения: 27
Собрал свой gem разработчик инструментов
Присоединился: 4 года назад

По-рабочему, 90% времени нужен только блок, то, что в do ... end или в фигурных скобках. Метод вызывает его через yield, ничего не объявляя:

def with_timing(label)
  started = Process.clock_gettime(Process::CLOCK_MONOTONIC)
  result = yield
  elapsed = Process.clock_gettime(Process::CLOCK_MONOTONIC) - started
  puts "#{label}: #{(elapsed * 1000).round} ms"
  result
end

users = with_timing("load users") { User.where(active: true).to_a }

def each_admin(&block)
  User.where(admin: true).find_each(&block)
end

square = ->(x) { x * x }
square.(4) # => 16

&block нужен, когда блок надо сохранить или передать дальше, как в each_admin. lambda и -> одно и то же, это ближе всего к твоим делегатам, их кладут в scope и в константы. proc в прикладном коде почти не встречается.


Ответ
2 ответа
Максим О
Присоединился: 2 года назад

Собрал свой gem студент
Сообщения: 22

а в чём тогда разница между proc и lambda? на собеседованиях на стажировку это спрашивают


Ответ
kirill_spb
Присоединился: 4 года назад

Собрал свой gem разработчик инструментов
Сообщения: 27

Две вещи. Lambda строго проверяет число аргументов, а proc нет: лишние отбросит, недостающие станут nil. И return в lambda выходит из самой лямбды, а в proc из метода, где proc создан:

def demo
  l = -> { return 1 }
  l.call
  pr = proc { return 2 }
  pr.call
  3
end

demo # => 2

Для собеседования этого хватит.


Ответ
artem_67
Сообщения: 18
Пишет тесты разработчик на Go
Присоединился: 4 года назад

в Python на этом месте просто передают функцию, и никто не страдает. но признаю, with_timing("...") { ... } читается приятно


Ответ