2013-09-14 3 views
2

я создал метод с кодомМетод вызова выдает ошибку «неопределенный метод»

def delayTime(time, intervalString) 
    if time > 0 
    sleep(time/time) 
    puts intervalString 
    time -=1 
    delayTime(time, intervalString) 
    end 
end 

но когда я называю его

delayTime(1, ".") 

он бросает ошибку

`<class:Main>': undefined method 'delayTime' for Main:Class (NoMethodError) 
+0

Полный контекст отсутствует. Этот код должен работать, поэтому моя гипотеза заключается в том, что контекст вызова отличается от контекста определения. – user2246674

+0

Что вы думаете? – sawa

+0

Мой вопрос в том, почему это ошибка. В программе почти ничего нет, всего несколько выражений 'puts' и if. Я не понимаю, почему он не работает. Полный код, особенно не мой, я просто делаю его более эффективным или что-то в этом роде, здесь: http://pastebin.com/JehGB7fK – IHazABone

ответ

1

Вы должны позвонить, как показано ниже:

Main.new.delayTime(1, ".") 

delayTime - метод экземпляра вашего класса Main. Таким образом, приемник должен быть экземпляром класса Main. Глядя на вашу ошибку, я уверен, что вы назвали ее Main.delayTime. Но вы не можете так назвать. Если вы хотите назвать это как Main.delayTime, то вам необходимо определить свой метод, как показано ниже:

def self.delayTime(time, intervalString) 
    if time > 0 
    sleep(time/time) 
    puts intervalString 
    time -=1 
    delayTime(time, intervalString) 
    end 
end 

Исправленная

class Main 
    #Variables 
    name = "" 
    answer_wonder = "" 
    answer_math = "" 
    result_math = 0 
    #End of Variables 
def self.delayTime(time, intervalString) 
    if time > 0 
     sleep(time/time) 
     puts intervalString 
     time -=1 
     delayTime(time, intervalString) 
    end 
end 
end #Class end 

Main.delayTime(1, ".") 
+0

Это просто thew ' ': неопределенный метод' delayTime 'для #

(NoMethodError) 'у меня. Это единственная строка, которую я должен изменить, или ...? – IHazABone

+0

Новый код - http://pastebin.com/tuF1LTL9 Я поставил все остальное как комментарий и сделал то, что вы сказали. Еще ошибка. Извините, вчера я только начал Ruby. – IHazABone

+0

@IHazABone Попробуйте сейчас .. :) Вы делаете беспорядок с основными вещами :) –

0

Ошибка вы получаете является результатом того, как рубин интерпретирует код. Ваш код состоит из определения класса с включенным корпусом класса (между class и окончательным end).

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

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

Это может быть достигнуто путем переноса вашей логики внутри метода, например.

class Main 
    def execute 
    ... 
    delayTime 
    ... 
    end 

    def delayTime 
    ... 
    end 
end 

Main.new.execute # Instantiate the class and execute the wanted method 

Однако, если вы действительно хотите, чтобы выполнить код во время загрузки, и до сих пор называют определенный метод, вам нужно сделать несколько изменений. Прежде всего вам нужно определить метод до того, как выполняется код вызова (во время загрузки, помните). Помимо определения его перед вызывающим кодом, вам нужно убедиться, что вы определяете его как метод класса (либо путем префикса метода с помощью self., либо путем определения определения класса с помощью синтаксиса class << self ... end и определения метода там). Это необходимо, так как экземпляр класса не известен как тело класса. Состояние курицы и яиц.

Модифицированная версия будет выглядеть примерно так:

class Main 
    def self.delayTime 
    ... 
    end 

    ... 
    self.delayTime # Could also be called as Main.delayTime 
    .... 
end 

И, наконец, пример, открыв определение класса:

class Main 
    class << self 
    def delayTime 
     ... 
    end 
    end 

    ... 
    self.delayTime # Could also be called as Main.delayTime 
    .... 
end 

Заметим, однако, что, помещая логику самого тела класса, вы можете столкнуться с некоторыми нежелательными проблемами, так как ваша программа выходит за рамки одного файла, и вы начинаете включать (require/load) несколько файлов. Но, это история на другой день.

+0

Итак, между 'class Main' и' end' для этого, я должен только объявлять переменные и/или методы? Все остальное выходит за пределы этого? – IHazABone

+1

Все зависит от того, чего вы хотите достичь. Судя по введенному вами коду (pastebin), я бы рекомендовал вам инкапсулировать всю вашу логику (включая переменные) внутри метода, который вы вызываете на экземпляр класса (путем вызова экземпляра 'Main.new.execute', если' execute '- это имя определенного метода). Другой вариант - сделать оба метода ('execute' и' delayTime') таким способом, чтобы не создавать экземпляр класса перед его вызовом. Например. 'Main.execute'. – simonnordberg

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