2016-10-30 5 views
-1

В основном я хочу что-то вроде этого:Запуск метода между каждым вызовом метода

some_method do 
    method1() 
    method2() 
    method3() 
end 

, где между каждым из этих 3-х методов, было бы sleep 5, я просто не хочу повторять sleep 5 после каждого вызов метода. Есть ли способ определить some_method, например между каждым вызовом метода, выполняется конкретный метод, например sleep 5? Я не хочу загрязнять свой код, вставив кучу команд sleep после каждого вызова метода.

+3

Создайте функцию, которая принимает список функций и выполняет каждый в цикле и добавляет спать после каждого вызова. Конечно, это возможно только в том случае, если каждая функция принимает 0 аргументов, иначе вам нужно обернуть каждую функцию в лямбда 0-arity. Idk Ruby, но если он способен, макрос может сделать это тоже. – Carcigenicate

ответ

2

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

module M 
    def method1 
    puts "method 1" 
    end 
    def method2 
    puts "method 2" 
    end 
    def method3 
    puts "method 3" 
    end 
end 

class A 
    include M 
    def method4 
    puts "method 4" 
    end 
    def execute_methods 
    M.instance_methods.each { |m| send m; sleep 5 } 
    end 
end 

A.new.execute_methods 
    # method 1 
    # method 2 
    # method 3 

Одним из преимуществ, включая модуль, содержащий методы, которые должны выполняться в том, что вы можете добавлять, удалять или переименовывать методы в модуле без изменения какой-либо другой код. Этот метод может быть потенциально полезным, например, при выполнении ряда методов проверки, что каждый вернуть true или false:

def validate(obj) 
    M.instance_methods.all? { |m| send m, obj } 
end 

Это также является пример методов, которые имеют аргументы и значение которых возврат используется.

+0

Уход, но это немного ограничительный, не так ли?Любая произвольная функция, которую вы хотели бы сделать, должна иметь делегат в модуле. – Carcigenicate

+0

@Carcigenicate, я не понимаю, что означает «делегат в модуле». –

+0

Вам понадобится сделать обертку вокруг любой функции, которую вы хотели использовать, не так ли? Например, я хотел сделать это со встроенной функцией 'map'. Мне нужно было бы создать в модуле функцию обертки, которая вызывает встроенную «карту», ​​не так ли? – Carcigenicate

0

Заметьте, я не знаю Ruby, так что это будет в javascripty-вкусе псевдокода и не будет использовать никаких «особых возможностей» Ruby.

Это, вероятно, самый простой способ добиться того, что вы ищете:

function execute_in_sequence(delay, fs) { 
    foreach(f in fs) { 
     f(); 
     sleep(delay); 
    } 
} 

Затем вы можете использовать его как:

function p() { 
    print(1); 
} 

execute_in_sequence(500, 
    [p, p, p] 
); 

Вы также могли бы избавиться от явного списка с помощью которые могут позволить вам написать его как:

execute_in_sequence(500, 
    p, 
    p, 
    p 
); 

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

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

0

Вот одна возможная реализация some_method. Параметры - это имена методов как символ (например: method1 для метода1()), и если задан блок, он выполняется после каждого вызова метода.

def method1 
    puts "Method1" 
end 

def method2 
    puts "Method2" 
end 

def method3 
    puts "Method3" 
end 

def some_method(*methods) 
    methods.each{|m| 
    send m 
    yield if block_given? 
    } 
end 

some_method(:method1, :method2, :method3) do 
    puts " Waiting 5 sec." 
    sleep 5 
end 

возвращает:

Method1 
    Waiting 5 sec. 
Method2 
    Waiting 5 sec. 
Method3 
    Waiting 5 sec. 

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

Смежные вопросы