Является ли блок Do тем же, что и оператор With? - PullRequest
1 голос
/ 14 июля 2009

Изучение Ruby и блока Do. Исходя из большого количества C #, я не видел много такого, что напоминало бы мне о Do, но потом VB пришло в голову с оператором With, который, как мне хотелось бы, был в C # (возможно, это так, и я его никогда не видел?). Два утверждения, Do и With, выглядят одинаково.

Является ли оператор With в VB таким же, как блок Do в Ruby?

EDIT:

Возьмите этот пример, объект ActiveRecord TheBook, сопоставленный с таблицей базы данных:

TheBook.new do |book|
 book.title = "my book"
 book.writer = "some author"
end

Я понимаю, что я получу, просто взглянув на это. Я знаю, что я получу новую запись в моей базе данных с вышеуказанной информацией, но я не знаю почему. Почему книга стала TheBook.new? Я читаю это справа налево?

Ответы [ 5 ]

8 голосов
/ 14 июля 2009

Нет. Блоки Ruby (то, что вы разделяете с помощью do и end) - это, в основном, замыкания . with в VB - это просто синтаксический сахар, чтобы вам не приходилось вводить имя переменной снова и снова.

5 голосов
/ 14 июля 2009

Будучи в основном разработчиком C # без особого опыта работы с Ruby, я понимаю ваше замешательство.

Если вы знакомы с концепцией анонимных делегатов в C # 2.0 и лямбда-выражений в C # 3.0, это имеет гораздо больший смысл.

Ваш пример Ruby ActiveRecord может быть выражен в C # 2.0 с использованием анонимных делегатов:

TheBook.New ((delegate TheBook book){
  book.title = "my book";
  book.author = "some author";
});

Или в C # 3.0 с использованием лямбда-выражения следующим образом:

TheBook.New (book => {book.title = "my book"; book.author = "some author"});

По существу, блок "do" вступает в игру, когда у вас есть методы, которые ожидают функцию в качестве аргумента или делегата в C #.

3 голосов
/ 14 июля 2009

Это не то же самое. Блок Ruby - это анонимная функция (технически, замыкание), которая может быть выполнена методом, которому она передана. Например, фрагмент, чтобы получить четные числа до 100:

(1..100).select do |num| 
  num % 2 == 0
end

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

(Обычно это записывается как (1..100).select {|num| num%2 == 0} - это не имеет значения. Синтаксис do в точности соответствует скобкам.)

2 голосов
/ 15 июля 2009

Я думаю, что именно WhyPoignant в своем уроке объяснил это так:

|varname| это как труба для направления значение каждой итерации в блок.

допустим, вы хотите прочитать каждую строку файла:

file.each_line do |line|
  puts line
end

file.each_line даст вам некоторые данные, и вы будете использовать |line| для направления этих данных в блок (здесь просто puts line)

Literraly: прочитать файл и для каждой строки выводит его на экран (если быть точным, стандартный вывод)

Я часто пишу свой код так: element s .each do |element| ...

1 голос
/ 14 июля 2009

Вы можете немного узнать о том, что делает этот метод, посмотрев на источник. Из ActiveRecord :: База:

def initialize(attributes = nil)
  @attributes = attributes_from_column_definition
  @attributes_cache = {}
  @new_record = true
  ensure_proper_type
  self.attributes = attributes unless attributes.nil?
  self.class.send(:scope, :create).each { |att,value| self.send("#{att}=", value) } if self.class.send(:scoped?, :create)
  result = yield self if block_given?
  callback(:after_initialize) if respond_to_without_attributes?(:after_initialize)
  result
end

Интересует этот вопрос result = yield self if block_given?. В ruby ​​метод yield вызывает блок, который был передан в функцию (в приведенном вами примере это будет часть между do и end) с любыми используемыми параметрами. В этом случае параметр, передаваемый блоку, равен self. Этот конкретный экземпляр блока фактически копирует функциональность with, упомянутую вами в Visual Basic, потому что он передает блок вновь созданному объекту ActiveRecord, но, как обсуждалось в других ответах, блоки Ruby имеют гораздо больше использует, чем это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...