29.01.2010, 16:10
|
|
|
|
Регистрация: 27.12.2008
Сообщений: 4,201
|
|
а можно увидеть, как эта функция на Ruby выглядела бы?
|
|
29.01.2010, 17:28
|
Профессор
|
|
Регистрация: 25.02.2008
Сообщений: 707
|
|
Сообщение от x-yuri
|
а можно увидеть, как эта функция на Ruby выглядела бы?
|
Ну, для начала общий пример (из Википедии):
# ruby
def foo
f = Proc.new { return "return from foo from inside proc" }
f.call # control leaves foo here
return "return from foo"
end
def bar
f = lambda { return "return from lambda" }
f.call # control does not leave bar here
return "return from bar"
end
puts foo # prints "return from foo from inside proc"
puts bar # prints "return from bar"
Замыкания, порождаемые Proc.new - при return-e могут завершать контекст, в котором были порождены.
Замыкания, порождаемые функцией lambda - не могут.
Касаемо массива, метода .each и фунарга - я проверил, в версии 1.8.6 - и lambda, почему-то, завершает порождаемый контекст. В версии 1.9.1. это исправлено:
def test1
fn = lambda {|x| return x}
[1, 2, 3].each(&fn) # процедура передаётся с амперсандом
return nil
end
def test2
fn = Proc.new {|x| return x}
[1, 2, 3].each &fn # скобки вызова - опциональны
return nil
end
puts test1 # 1 - в 1.8.6, nil (правильно) - в 1.9.1
puts test2 # 1 - правильно
Есть ещё третий способ создать замыкание в Ruby - это блок кода (который можно преобразовать в процедуру). Различные методы (типа .each) как раз и используются с этими блоками кода.
def test3
[1, 2, 3].each {|x| return x} # сразу описываем блок кода
nil # слово return - тоже опциональное
end
puts test3 # 1 - при использовании блока, тоже выход из порождающего контекста
Последний раз редактировалось Dmitry A. Soshnikov, 30.01.2010 в 12:23.
|
|
29.01.2010, 20:20
|
|
|
|
Регистрация: 27.12.2008
Сообщений: 4,201
|
|
интересно... По поводу js я бы сделал так (поиск первого элемента, удовлетворяющего условию)
function getElement() {
return [1, 2, 3].findFirst(function( element ) {
return element % 2 == 0;
});
}
alert(getElement());
т.е. как минимум отсутствие такой функциональности не создает никаких сложностей. Кроме того, я бы даже сказал, что наличие таких возможностей усложняет код: глядя на return так сразу и не скажешь, что он завершает. Хотя это уже, конечно, "предварительное" мнение - надо попробовать эту штуку в действии
Как я понял, return в замыкании, созданном с помощью Proc.new завершает функцию, в которой было создано замыкание. И использовать его, за пределами этой функции смысла не имеет
может еще какие-нибудь примеры использования Proc.new есть? Т.е. на данный момент я вижу, что это можно использовать для поиска первого элемента
Сообщение от Dmitry A. Soshnikov
|
Ну, для начала общий пример (из Википедии):
|
не додумался в статью про замыкания заглянуть
Последний раз редактировалось x-yuri, 29.01.2010 в 20:23.
|
|
30.01.2010, 01:28
|
Профессор
|
|
Регистрация: 25.02.2008
Сообщений: 707
|
|
Сообщение от x-yuri
|
Хотя это уже, конечно, "предварительное" мнение
|
Ага, привычка к конкретной технологии, анализ через её призму. В Ruby же это описывается в доках, так что, для тех, кто изначально изучал Ruby - это не будет казаться чем-то странным.
С другой стороны, последний драфт стандарта по Ruby появился недавно (я не в курсе, вышла ли уже первая официальная версия), возможно, там что-то изменят, а пока все доки по руби - это исходники и доки на официальном сайте. Когда появится стандарт, можно будет однозначно говорить, как должно быть.
Сообщение от x-yuri
|
Как я понял, return в замыкании, созданном с помощью Proc.new завершает функцию, в которой было создано замыкание. И использовать его, за пределами этой функции смысла не имеет
|
Да, но это касается только ключевого слова return. Proc.new выходит из метода. Если вызвать Proc.new с "return" вне метода, будет ошибка - "неожиданный return".
fn = Proc.new {|x| return x}
fn.call 10 # ошибка
fn1 = Proc.new {|x| x}
fn1.call 10 # 10
def foo
fn = Proc.new do |x| # альтернативная запись блока {...} == do...end
return x
end
fn.call 10
return 'сюда не дошли'
end
foo # 10
Есть ещё несколько случаев, когда return из Proc.new завершится с ошибкой (когда контекст уже мёртв, когда вызывается в другом треде, др.)
Вообще, можно выделить даже не 3, а целых 7 способов создать замыкания в Ruby (но они будут сводиться к 3-ём; остальные 4 - вариации/комбинации предыдущих).
Сообщение от x-yuri
|
может еще какие-нибудь примеры использования Proc.new есть? Т.е. на данный момент я вижу, что это можно использовать для поиска первого элемента
|
Ну, не первого, а любого/группы (и не обязательно поиска). Придумай другие примеры
Я рассказываю, как есть (не привязываясь к ES, либо к другой технологии) - на твою фразу, что "не надо этого хотеть". Иногда это удобно, но в ES такой возможности нет.
Нравится тебе это или нет, хочешь ли ты от этого отгородиться или нет, решил ли ты для себя, что это нужно/не нужно: это есть (в некоторых языках) и разработано с конкретной целью
Последний раз редактировалось Dmitry A. Soshnikov, 30.01.2010 в 12:23.
|
|
30.01.2010, 01:57
|
|
|
|
Регистрация: 27.12.2008
Сообщений: 4,201
|
|
Сообщение от Dmitry A. Soshnikov
|
Иногда это удобно, но в ES такой возможности нет.
|
ключевое слово иногда. Причем тем, кому оно надо, спрашивать вряд ли будут, потому что и так знают. В общем, в таких случаях вариантов ответа не много, имхо
|
|
30.01.2010, 11:58
|
Профессор
|
|
Регистрация: 25.02.2008
Сообщений: 707
|
|
Сообщение от x-yuri
|
ключевое слово иногда
|
Нет, это моё слово было (в моём предложении). Кому-то, может, это всегда удобно.
|
|
30.01.2010, 17:39
|
|
|
|
Регистрация: 27.12.2008
Сообщений: 4,201
|
|
Сообщение от Dmitry A. Soshnikov
|
Кому-то, может, это всегда удобно.
|
ну может и есть такие люди, но мы же не будем брать пример с кого попало
|
|
30.01.2010, 19:17
|
Профессор
|
|
Регистрация: 25.02.2008
Сообщений: 707
|
|
Ну, здесь я уже не смогу помочь. Я рассказал и объяснил, как есть: что с этим делать тебе и как тебе к этому относиться - решать только тебе
А то, что есть такой механизм и, что он существует независимо от того, понимаешь ли/принимаешь ли ты его, и что фраза в данном случае "не надо этого хотеть" - неверна - это истина.
Сообщение от x-yuri
|
но мы же не будем брать пример с кого попало
|
Это твоё видение и твоё мнение, меня не причисляй (данная фраза для меня является демагогией).
|
|
30.01.2010, 21:35
|
|
|
|
Регистрация: 27.12.2008
Сообщений: 4,201
|
|
Сообщение от Dmitry A. Soshnikov
|
А то, что есть такой механизм и, что он существует независимо от того, понимаешь ли/принимаешь ли ты его, и что фраза в данном случае "не надо этого хотеть" - неверна - это истина.
|
я не говорил никогда. Я говорил, что надо учитывать реальную проблему человека, а не формально отвечать на вопрос
Сообщение от Dmitry A. Soshnikov
|
Это твоё видение и твоё мнение, меня не причисляй (данная фраза для меня является демагогией).
|
я говорил о тех, которые всегда используют Proc.new, и никогда lambda. Потому что это либо фанатизм, либо пофигизм
|
|
30.01.2010, 22:37
|
Профессор
|
|
Регистрация: 25.02.2008
Сообщений: 707
|
|
Сообщение от x-yuri
|
я не говорил никогда. Я говорил, что надо учитывать реальную проблему человека, а не формально отвечать на вопрос
|
Да нет, я прекрасно понимаю, что изначально ты процитировал чью-то эту фразу, чтобы показать, что "надо есть суп ложкой" (хотя, не обязательно). Я отметил, что для этого желания (завершить из вложенной функции внешнюю) есть обоснования и, что они реализованы в некоторых языках.
Кстати, однозначные призывы "есть суп ложкой" тоже можно нарушать с целью экспериментов от устоявшихся паттернов (ну, естественно, для этого должны быть обоснованные мотивации).
А дальше ты принял позицию, выдающую это за какую-то ненужную вещь, и я должен тебе доказывать, почему это не так. Но, ведь, цель нашей беседы не в этом, правда? Я просто тебя информировал, без определения, плохая это вещь или нет. Здесь ты сам уже примешь решение.
Сообщение от x-yuri
|
я говорил о тех, которые всегда используют Proc.new, и никогда lambda. Потому что это либо фанатизм, либо пофигизм
|
Мне показалось, говоря о "ком попало", ты говоришь о людях, которые могут вообще использовать return для выхода из вложенной функции, завершая внешнюю. Если я не так понял, извини.
Там есть ещё различия. Например, Proc.new (в отличие от lambda) не проверяет точное количество параметров (что также может быть удобно в определённых случаях).
Если интересно - вот исходник на Ruby (выполненный даже больше в виде статьи) о замыканиях - http://innig.net/software/ruby/closures-in-ruby.rb - достаточно подробно описаны различные случаи (можешь сохранить, читать в редакторе с подсветкой, скрипт полностью рабочий и запускаемый).
Последний раз редактировалось Dmitry A. Soshnikov, 30.01.2010 в 23:13.
|
|
|
|