Какую выгоду я могу получить с блоками по сравнению с обычными методами? - PullRequest
4 голосов
/ 24 января 2011

Я программист на Java и изучаю Ruby ...

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

Почему в блоке есть код, который нельзя использовать повторно?

Мне бы хотелось несколько примеров кода ...

Спасибо за помощь!

Ответы [ 2 ]

9 голосов
/ 24 января 2011

Рассмотрим некоторые вещи, для которых вы будете использовать анонимные классы в Java. например часто они используются для подключаемого поведения, такого как прослушиватели событий, или для параметризации метода, который имеет общий макет.

Представьте, что мы хотим написать метод, который принимает список и возвращает новый список, содержащий элементы из данного списка, для которых заданное условие выполняется. В Java мы написали бы интерфейс:

interface Condition {
    boolean f(Object o);
}

и тогда мы могли бы написать:

public List select(List list, Condition c) {
    List result = new ArrayList();
    for (Object item : list) {
        if (c.f(item)) {
            result.add(item);
        }
    }
    return result;
}

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

List even = select(mylist, new Condition() {
    public boolean f(Object o) {
        return ((Integer) o) % 2 == 0;
    }
});

Чтобы написать эквивалент в Ruby, это может быть:

def select(list)
  new_list = []
  # note: I'm avoid using 'each' so as to not illustrate blocks
  # using a method that needs a block
  for item in list
    # yield calls the block with the given parameters
    new_list << item if yield(item)
  end
  return new_list
end

и затем мы могли бы выбрать четные числа просто

even = select(list) { |i| i % 2 == 0 }

Конечно, эта функциональность уже встроена в Ruby, так что на практике вы просто сделаете

even = list.select { |i| i % 2 == 0 }

В качестве другого примера рассмотрим код для открытия файла. Вы могли бы сделать:

f = open(somefile)
# work with the file
f.close

но вам нужно подумать о том, чтобы поместить close в блок ensure на случай, если во время работы с файлом возникнет исключение Вместо этого вы можете сделать

open(somefile) do |f|
  # work with the file here
  # ruby will close it for us when the block terminates
end
2 голосов
/ 24 января 2011

Идея, лежащая в основе блоков, заключается в том, что это сильно локализованный код, где полезно иметь определение на сайте вызова.Вы можете использовать существующую функцию в качестве аргумента блока.Просто передайте его как дополнительный аргумент и добавьте префикс &

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