2016-02-13 7 views
0

Я новичок в программировании, особенно в Ruby, поэтому я делаю некоторые базовые проекты. У меня есть этот код, и, насколько я знаю, он должен работать, но он дает результаты, которых я не ожидаю.Подсветка не работает

Программа принимает a и B и возвращает a^b. Я сделал это как упражнение по программированию, поэтому почему я не просто пошел ** b.

class Exponate 
    attr_accessor :args 

    def initialize args = {} 
    @args = args 
    @ans = nil 
    end 

    def index 
    @args[:b].times { 
     @ans = @args[:a] * @args[:a] 
    } 
    puts @ans 
    end 
end 

e = Exponate.new(:a => 32, :b => 6) 
e.index 

e.args[:a] = 5 
e.index 

Возвращает

1024  # Should be 1_073_741_824 
25  # Should be 15_625 

Но они, безусловно, не то, что

+0

Почему не просто '@args [: a] ** (@args [: b] + 1)'? – spickermann

+0

@spickermann Поскольку я хотел сделать это вручную, как упражнение по программированию –

+0

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

ответ

1

Вы можете написать так:

class Exponate 
    attr_accessor :args, :ans 

    def initialize args = {} 
    @args = args 
    end 

    def index 
    @ans = 1 # multiplication will start from 1 
    @args[:b].times { 
     @ans *= @args[:a] #same as @ans = @ans * @args[:a] 
    } 
    puts @ans 
    end 
end 
+0

Спасибо! Единственное, что я изменил после этого, - это перемещение @ans = 1 из инициализации и индекса, потому что в противном случае оно не будет сброшено. –

+1

да, ты прав) – Ilya

1

@ans = @args[:a] * @args[:a] будет возвращать то же значение, независимо от того, сколько раз вы должны каким-то образом ссылаться на переменную аккумулятора, чтобы использовать цикл ле.

Использование переменной экземпляра для локального не кажется правильным - их время жизни больше, поэтому после выхода метода они не могут быть собраны, если весь объект все еще упоминается где-то. Также @ s более подвержены ошибкам - если вы сделаете опечатку (например - @asn вместо @ans), вы получите nil вместо NameError, это может быть сложнее для отладки, поэтому лучше писать так:

def index 
    ans = 1 
    args[:b].times { 
    ans *= args[:a] 
    } 
    puts ans 
end 

для петель с аккумулятором в рубин, лучше использовать Enumerable#inject:

@ans = @args[:b].times.inject(1){|acc,v| acc * @args[:a]} 

таким образом, это менее вероятно, забыть инициализацию.

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

  • Нет связанных вопросов^_^