2014-09-25 4 views
-1

Запуска следующего кода:рубин возвращается неопределенным метод + для ноля: nilClass

# experiment 
time = 5000 
# when time reaches 10000, I'm off duty 
def speedup_time(incre) 
    time += incre 
    yield(time) 
end 

puts "is the day over yet? #{speedup_time(2000){ 
    if incre >= 10000 
    "yes: #{time}" 
    else 
    "no: #{time}" 
    end 
}}" 

Я столкнулся с этой ошибкой: undefined method "+" for nil:nilClass.

+0

Ruby должен 'поднять неопределенную локальную переменную или метод 'time'', но parser evulate' time' to 'nil' и я не могу понять, почему' time' равно 'nil' в' def' scope? –

+0

@ Зелёный, потому что синтаксический анализатор видит это: 'time =', поэтому парсер создает переменную, называемую временем, и отмечает ее как локальную переменную. Это означает, что существует временная переменная, но ей еще не присвоено значение. Затем выполняется код, и возникает ошибка. Парсер будет делать это, даже если это невозможно для выполнения оператора присваивания, например. 'if false; время = 10; end' – 7stud

ответ

2

time переменная за пределами области действия (метод определения в Ruby имеет собственную область видимости и не может видеть никаких внешних переменных). Попробуйте следующее:

# when time reaches 10000, I'm off duty 
def speedup_time(incre) 
    time = 5000 
    time += incre 
    yield(time) 
end 

И вы второе выражение неправильно. Я думаю, что должно быть что-то вроде:

speed_var = speedup_time(2000) do |time| 
    if time >= 10000 
    "yes: #{time}" 
    else 
    "no: #{time}" 
    end 
end 
puts "is the day over yet? #{speed_var}" 

Или короткий с тройным оператором:

speed_var = speedup_time(2000) { |time| (time >= 10000) ? "yes: #{time}" : "no: #{time}" } 
puts "is the day over yet? #{speed_var}" 

или:

puts %Q|is the day over yet? #{speedup_time(2000){ |time| (time >= 10000) ? "yes: #{time}" : "no: #{time}"}}| 
+0

Я думал об использовании урожая и адаптировал это к обещанию. Тогда стиль, как я привык в javascript, есть способ адаптировать это с урожаем. – user2167582

+0

@ user2167582 Посмотрите ответ на обновление, если я понимаю правильно. –

+0

круто, поэтому 'something end' похоже на замену скобок:' {} ', они определяют и делят все блоки в ruby? – user2167582

2

I was thinking of using the yield and adapt this to a promise.then style as I was accustomed to in javascript, is there a way to adapt this with yield.

Вы собираетесь должны изучить блоки немного больше потому что это не будет работать:

def do_stuff(x) 
    yield 
end 


do_stuff(10) { puts x } 


--output:-- 
2.rb:6:in `block in <main>': undefined local variable or method `x' for main:Object (NameError) 
    from 2.rb:2:in `do_stuff' 
    from 2.rb:6:in `<main>' 

Довольно ясно, что вы потеряли, когда дело доходит до областей в рубине. Получите начальную рубиновую книгу. Прочтите. Ruby не является javascript.

#----A def creates a new scope--+ 
def do_stuff    # | 
    x = 10     # | 
end      # | 
#-------------------------------+ 
#...which means nothing inside that box can see anything outside the box 
#except for constants, which are visible everywhere 

y = 20 

p = Proc.new do #Proc.new and lambda create anonymous functions in ruby 
    puts y 
    puts x 
    puts z 
end 

def test(p) 
    z = 30 
    p.call #execute proc, can also be written as p[] 
end 

test p 

Играйте с этим примером, комментируя различные высказывания.

+0

спасибо, им помолодел какой-то синтаксис и практику, прежде чем полностью потеряться в книгах. – user2167582

+1

+1 'javascript' содержат сумасшедшие правила области IMO. –

+0

@ Зелёный, Да, как и переменные цикла, это глобальные переменные. :( – 7stud

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