2012-04-14 3 views
1

Я сделал небольшую DSL-программу для добавления напитков в массив. Это довольно простой пример использования instance_eval и &block для создания быстрой программы.Создание блока Ruby возвращает массив?

Вот программа:

class Drinks 
    def initialize(&block) # Initialize drinks 
    @drinks = [] 
    instance_eval &block 
    end 

    def drink(d) 
    @drinks << d 
    end # Add drink 

    def all_drinks 
    puts @drinks 
    end 

end 

add_drinks = Drinks.new do 
    drink "water" 
    drink "soda" 
    drink "juice" 
end 

add_drinks.all_drinks 

План должен сделать сам add_drinks автоматического возврата, так что вы не должны использовать add_drinks.all_drinks. Возможно ли это? Благодарю.

+0

«авто-возврат себя»? Но это не то, что вы хотите, вам нужен массив? –

ответ

5

Вы можете наследовать Напитки из массива, так что вы можете работать с новым экземпляром, как с массивом

class Drinks < Array 
    def initialize(&block) # Initialize drinks 
    instance_eval &block 
    end 

    def drink(d) 
    self << d 
    end # Add drink 
end 

add_drinks = Drinks.new do 
    drink "water" 
    drink "soda" 
    drink "juice" 
end 

add_drinks # => ["water", "soda", "juice"] 
+1

Я понимаю, что это не в тему, но я бы просто хотел сказать, что это помогло мне исправить проблему и сделать мой код менее подробным + проще, поэтому спасибо, я не знаю, почему, но я не рассматривал возможность делать «instance_eval» внутри инициализатора, а не за его пределами в конструкторе, так спасибо. – Thermatix

1

Вы могли бы хотеть переосмыслить то, что объект и как он ведет себя. Возможно, так:

class Drinks 
    def initialize(&block) 
    @drinks = [] 
    instance_eval &block 
    end 

    def add(d) 
    @drinks << d 
    end 

    def show 
    puts @drinks 
    end 
end 

drinks = Drinks.new do 
    add "water" 
    add "soda" 
    add "juice" 
end 

drinks.show 
Смежные вопросы