Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Сущность yield statement, примеры есть? 
:(
    Опции темы
Andi
Дата 13.9.2006, 12:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 46
Регистрация: 28.8.2006

Репутация: нет
Всего: нет



В Руби есть интересная языковая конструкция под названием
yield statement.Обьясните на пальцах ее физический смысл.
Хорошо бы ссылки (или коды программ) с конкретным применением.
Кто что знает,отзовитесь!
PM MAIL   Вверх
simanyay
Дата 13.9.2006, 17:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Антон Ковалёв
****


Профиль
Группа: Участник
Сообщений: 2053
Регистрация: 22.8.2002

Репутация: 6
Всего: 36



Чисто-конкретное применение в Rails

Есть основной шаблон (layout):

Код

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html>
  <head>
    <title>Чисто-конкретно</title>
  </head>
  <body>
    <div id="left_column">
      <%= yield :left %>
    </div>
    <div id="right_column">
      <%= yield :right %>
    </div>
  </body>
</html>


При помощи такого кода мы в разных вьюшках можем пихать в эти места разный код. Пример:
Код

<% content_for :left do %>
  <p>левота</p>
<% end %>

<% content_for :right do %>
   <p>правота</p>
<% end %>


Таким образом на выходе будет:
Код

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html>
  <head>
    <title>Чисто-конкретно</title>
  </head>
  <body>
    <div id="left_column">
      <p>левота</p>
    </div>
    <div id="right_column">
      <p>правота</p>
    </div>
  </body>
</html>


Будет время, напишу примеры из голенького ruby.


--------------------
«It's better to be a pirate than to join the Navy» — Steve Jobs.
PM MAIL WWW   Вверх
Pete
Дата 13.9.2006, 20:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 318
Регистрация: 5.1.2006
Где: Москва

Репутация: 2
Всего: 12



yield позволяет вызывать переданный методу блок кода:

Код

def f
  puts 'begin'
  yield
  puts 'end'
end

f { puts 'center' }

результат:
Код

begin
center
end


Также можно вызывать блок с параметрами, передаваемыми при вызове yield:

Код

def f
  yield( 10, '3' )
end

f {|a, b| puts b*a }   # => 3333333333


«Свои методы с блоками» на wikibooks

Это сообщение отредактировал(а) Pete - 13.9.2006, 20:29


--------------------
Совет учиться на ошибках других бесполезен; научиться чему-либо можно только на собственных ошибках. (Бернард Шоу)
Не откладывай на завтра то, что можешь сделать сегодня. (Пословица)
А теперь выпишем точное значение числа пи... (Препод)
Жахни, Пендальф! © Гоблин
PM   Вверх
max_lapshin
Дата 13.9.2006, 21:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 10.9.2006
Где: Москва

Репутация: 2
Всего: 3



Тут идея в чем. Блоки — часть функционального программирования.

Мы берем какую-то функциональность в виде объекта, но запускать ее будем только тогда, когда она нам будет нужна.
Аналог — взять адрес функции в C, после чего запустить ее по необходимости. Тоже самое, только гораздо примитивнее.

Соответственно, yield — полный аналог процедуры запуска функции не по ее прямому имени, а через переменную, в которую ее записали.

Разница в том, что при запуске метода может быть передан блок. В описании метода он никак не фигурирует (впрочем, его можно задать явно), соответственно, yield — вызов того самого единственного блока, который был передан неявно в метод.
PM MAIL WWW ICQ Jabber   Вверх
Andi
Дата 14.9.2006, 08:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 46
Регистрация: 28.8.2006

Репутация: нет
Всего: нет



Выходит что yield это анонимная рекурсия,правильно я понял?
PM MAIL   Вверх
Pete
Дата 14.9.2006, 09:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 318
Регистрация: 5.1.2006
Где: Москва

Репутация: 2
Всего: 12



Не совсем. yield вызывает только ассоциированный с функцией блок кода. Функция не вызывает сама себя (в общем случае), она лишь обрабатывает некоторый код, переданный ей при вызове.


--------------------
Совет учиться на ошибках других бесполезен; научиться чему-либо можно только на собственных ошибках. (Бернард Шоу)
Не откладывай на завтра то, что можешь сделать сегодня. (Пословица)
А теперь выпишем точное значение числа пи... (Препод)
Жахни, Пендальф! © Гоблин
PM   Вверх
skalex
Дата 14.9.2006, 15:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Хороший человек
**


Профиль
Группа: Участник Клуба
Сообщений: 895
Регистрация: 2.4.2004

Репутация: 5
Всего: 23



Ребята, объясните попроще, а? smile
PM   Вверх
Pete
Дата 14.9.2006, 20:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 318
Регистрация: 5.1.2006
Где: Москва

Репутация: 2
Всего: 12



skalex, куда уж проще?  smile 
Как правильно выразился max_lapshin, конструкцию yield можно понимать как тело некоторой функции, которая вызывается использованием ключевого слова yield. Примеры даны вполне очевидные.

Добавлено @ 20:24 
В моем последнем примере:
Код

def f
  yield( 10, '3' )
end
f {|a, b| puts b*a }   # => 3333333333

фактически написано вот что:
Код

def f
  a, b = 10, '3'  # a = 10; b = '3'
  puts b*a  # b раз напечатать переменную a
end


Это сообщение отредактировал(а) Pete - 14.9.2006, 20:24


--------------------
Совет учиться на ошибках других бесполезен; научиться чему-либо можно только на собственных ошибках. (Бернард Шоу)
Не откладывай на завтра то, что можешь сделать сегодня. (Пословица)
А теперь выпишем точное значение числа пи... (Препод)
Жахни, Пендальф! © Гоблин
PM   Вверх
Void
Дата 14.9.2006, 21:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


λcat.lolcat
****


Профиль
Группа: Участник Клуба
Сообщений: 2206
Регистрация: 16.11.2004
Где: Zürich

Репутация: 1
Всего: 173



Цитата(max_lapshin @  13.9.2006,  23:28 Найти цитируемый пост)
Соответственно, yield — полный аналог процедуры запуска функции не по ее прямому имени, а через переменную, в которую ее записали.

Не совсем. yield и блоки — это скорее ближе к сопроцедурам. Есть одно весьма существенное отличие от функций высшего порядка: из блоков Ruby возможен нелокальный возврат. Вызывая функцию, мы можем быть уверены, что она вернёт нам управление. Даже если будет выброшено исключение, мы будем иметь возможность перехватить его. Блок же может передать управление в контекст, в котором он был создан.
Например:
Код
def hof(f) # функция высшего порядка
    puts f # вызываем переданную в качестве параметра функцию
end

def foo
    puts 'We are in foo'
    return 'foo return value'
end

def block_yield
    puts yield
    # Если переданный блок сделает return, 
    # мы сюда никогда не попадём!
    puts 'Normal exit'
end

def caller
    block_yield {
        puts 'In the block'
        'return some value to the block caller'
    }
    block_yield {
        puts 'In the block'
        return 'non-local return'
    }
end

puts 'Higher order function:'
hof(foo)
puts 'Blocks:'
puts caller



--------------------
“Coming back to where you started is not the same as never leaving.” — Terry Pratchett
PM MAIL WWW GTalk   Вверх
max_lapshin
Дата 15.9.2006, 00:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 10.9.2006
Где: Москва

Репутация: 2
Всего: 3



Код

> block_yield { "lala"; return false;}
LocalJumpError: unexpected return
        from (irb):6
        from (irb):2:in `block_yield'
        from (irb):6
        from :0

PM MAIL WWW ICQ Jabber   Вверх
Void
Дата 15.9.2006, 07:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


λcat.lolcat
****


Профиль
Группа: Участник Клуба
Сообщений: 2206
Регистрация: 16.11.2004
Где: Zürich

Репутация: 1
Всего: 173



Цитата(max_lapshin @  15.9.2006,  02:44 Найти цитируемый пост)
LocalJumpError: unexpected return

Естественно. Куда ему return'аться с toplevel? А если бы блок с return был создан в контексте функции, то и возвращался бы из этой функции. Приведённый мной выше код отрабатывает, как предполагается, на 1.8.5.


--------------------
“Coming back to where you started is not the same as never leaving.” — Terry Pratchett
PM MAIL WWW GTalk   Вверх
Andi
Дата 15.9.2006, 08:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 46
Регистрация: 28.8.2006

Репутация: нет
Всего: нет



Примеры очень даже ничего.
А еще говорят что Руби легок в понимании и освоении!!!
!!!Это неправда!!!
Да на уровне путсов и стрингов с аррэями все понятно.
Но когда начинается высший пилотаж-тут уж извините!
Надо больше примеров и притом с разьяснениями!
Если кто то еще чего нибудь подкинет будет весьма интересно!

Это сообщение отредактировал(а) Andi - 15.9.2006, 08:41
PM MAIL   Вверх
max_lapshin
Дата 15.9.2006, 09:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 10.9.2006
Где: Москва

Репутация: 2
Всего: 3



2Andi: говорят, что С++ легок в понимании. Это говорят люди, которые не видели шаблонов =)

Концепция блоков вообще достаточно непростая, поэтому нельзя здесь хотеть примитивных решений.
Примеров дохрена: открываем сырцы рельс и читаем. Если неясно, почему оно и как, открываем сырцы руби и смотрим. Я делаю так.
PM MAIL WWW ICQ Jabber   Вверх
Pete
Дата 15.9.2006, 23:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 318
Регистрация: 5.1.2006
Где: Москва

Репутация: 2
Всего: 12



Цитата(Andi @  15.9.2006,  09:40 Найти цитируемый пост)
А еще говорят что Руби легок в понимании и освоении!!!

Конечно, легок. На начальной стадии обучения. Только вряд ли на этой стадии нужен yield. Наличие сложных конструкций никак не уменьшает количество простых.


--------------------
Совет учиться на ошибках других бесполезен; научиться чему-либо можно только на собственных ошибках. (Бернард Шоу)
Не откладывай на завтра то, что можешь сделать сегодня. (Пословица)
А теперь выпишем точное значение числа пи... (Препод)
Жахни, Пендальф! © Гоблин
PM   Вверх
Void
Дата 15.9.2006, 23:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


λcat.lolcat
****


Профиль
Группа: Участник Клуба
Сообщений: 2206
Регистрация: 16.11.2004
Где: Zürich

Репутация: 1
Всего: 173



Цитата(max_lapshin @  15.9.2006,  11:27 Найти цитируемый пост)
говорят, что С++ легок в понимании.

 smile Кто? Мне такие безумцы ещё не встречались smile


--------------------
“Coming back to where you started is not the same as never leaving.” — Terry Pratchett
PM MAIL WWW GTalk   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Ruby: Общие вопросы"
source777
  • С чего начать? начинаем
  • Ссылки на полезные ресурсы смотрим тут
  • Обязательно следуйте правилам Vingrad.
  • Пожалуйста, прочитайте рекомендации по работе в форуме и навигации по Vingrad.
  • Для вставки кодов Ruby используйте тег: [code=ruby]код[/code]. Когда в будущем подсветка синтаксиса для Ruby будет реализована, весь исходных код преобразится.
  • Используйтe чекбокс "Транслит" (возле кнопок кодов), если у Вас нет русских шрифтов.
  • Помните, для каждого вопроса должна быть своя тема.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, source777.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Ruby: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1457 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.