2015-05-29 4 views
1

В настоящее время я изучаю Ruby и нажимаю какое-то поведение, которое я не совсем понимаю. В приведенном ниже примере кода у меня есть два до цикла, каждый по своему методу. При выполнении until_test он выводит цикл 10 20 10 20 10 20 навсегда, но при выполнении second_until_test он ведет себя так, как я ожидаю, выводя только 10 20. Похоже, что по какой-то причине код теперь, я не могу изменять переменные, переданные как параметры. Я знаю, что ответ на этот вопрос, вероятно, очень прост, но я не смог понять это или найти ответ здесь после поиска. Каков правильный способ успешно выполнить параметры, как я пытаюсь сделать в until_test?Невозможно получить доступ к методу переменной внутри, переданному как параметр

Заранее благодарен!

def until_test 
    num = 10 
    until num == 20 
     do_this(num) 
    end 
end 

def second_until_test 
    num = 10 
    until num == 20 
     puts num 
     num = 20 
     puts num 
    end 
end 

def do_this(variable) 
    puts variable 
    variable = 20 
    puts variable 
end 
+0

Возможный дубликат ['pass parameter by reference' в Ruby?] (Http://stackoverflow.com/questions/161510/pass-parameter-by-reference-in-ruby) – jcm

ответ

0

Ваша проблема здесь имен ... В second_until_test, Num справедливо для метода, поэтому он будет изменен внутри цикл до конца.

В until_test, вы передаете Num в качестве аргумента другой метод, который не будет непосредственно изменить переданный объект, если не утверждать Num к возвращаемому значению метода:

def until_test 
    num = 10 
    until num == 20 
    num = do_this(num) 
    end 
end 

def do_this(variable) 
    puts 20 
    variable = 20 
    # this method has to return the value for num 
    variable # or return variable, or return 20... 
end 

TLDR: NUM until_test в не меняет значение, поэтому он будет зависеть навсегда.

0

Я установил вас проблемы здесь:

def until_test 
 
    num = 10 
 
    until num == 20 
 
     num = do_this(num) 
 
    end 
 
end 
 

 
def second_until_test 
 
    num = 10 
 
    until num == 20 
 
     puts num 
 
     num = 20 
 
     puts num 
 
    end 
 
end 
 

 
def do_this(variable) 
 
    puts variable 
 
    variable = 20 
 
    puts variable 
 
\t return variable 
 
end 
 

 
until_test

+1

Пожалуйста, не просто предоставляйте рабочие решение, попробуйте объяснить, почему вы это сделали. – Ninigi

0

Другие ответы верны. Причина, по которой вы получаете цикл forever в until_test, заключается в том, что ваш метод do_this не возвращает вашу измененную переменную. Вызов путы не возвращает значение параметра, передаваемого, но nil, так что это означает, что вы назначаете num является nil, а не требуемый модифицированный выходной :)

В любом случае, просто разделяя другой способ убить кошку :)

В рубине есть что-то, что вы называете переменной экземпляра. Любая модификация переменной, сделанная в вашем скрипте, будь то другие методы, изменит значение переменной. Его можно просто объявить, добавив @ к переменной. Вы также можете использовать $, чтобы сделать его глобальным. Спасибо Эрик за указание, что из хахаха ...

Реализация этого на ваш код будет выглядеть следующим образом:

@num 
def until_test 
    @num = 10 
    until @num == 20 
     do_this(@num) 
    end 
end 

def second_until_test 
    @num = 10 
    until @num == 20 
     puts @num 
     @num = 20 
     puts @num 
    end 
end 

def do_this(variable) 
    puts variable 
    variable = 20 
    @num = variable 
    puts variable 
end 
+0

Не глобальные переменные с префиксом '$'? Я предполагаю, что вы говорите, это переменная экземпляра ('@'), по сути, действует как глобальная переменная, если она определена до и вне методов, использующих их? Спасибо за ответ, кстати. Я бы дал вам голосование, но пока не хватает очков! –

+0

Oopps hahaha ... спасибо за исправление .. Да, я имею в виду переменную экземпляра :) В любом случае глобальная переменная будет работать одинаково :) Lemme edit that hahaha –

0

Выбранный ответ является лучшим вариантом, хотя Джейсон дает альтернативный метод.

Чтобы уточнить ответ Джейсона, переменная экземпляра доступна для всех методов, определенных в методе объекта, включая вложенные методы.

class Dog 
    def dog_things 
    @dog = "Rex" 
    def bark 
     puts "#{@dog} goes 'bark, bark'" 
    end 
    bark 
    end 
end 

Dog.new.dog_things 
=> "Rex goes 'bark, bark'" 

И в Ruby, даже если вы не определили классы или объекты, вы, тем не менее, всегда в объекте. Это называется main, и это объект класса Object.

puts self 
=> main 
puts self.class 
=> Object 

Разница между экземпляром и глобальным переменным является то, что если вы определяете класс, переменный экземпляр вы установили перед созданием класса не доступно в классе (хотя он может иметь другой переменный экземпляр с тем же именем) ,

Глобальные переменные, однако, после определения, доступны везде, во всех классах и вне классов.