2014-02-09 5 views
2

Есть что-то, что я не понимаю о ruby ​​переменной экземпляра класса или методам **. Итак, у меня есть этот код, который продолжает давать мне эту ошибку, и я не могу понятьМетоды и переменные экземпляров Ruby

Похоже, что ruby ​​думает, что я пытаюсь вызвать Float.in_celsius, но я хочу сделать этот вызов в своем экземпляре класса.

#----------------------------------- 
def ftoc(fr) 
fr = fr.to_f 
if (fr == 32) 
    c = 0 
elsif (fr == 212) 
    c = 100 
else 
    c = (fr-32.0)*(5.0/9.0) 
end 

return c 
end 

def ctof (cl) 
cl = cl.to_f 
f = (cl*(9.0/5.0))+32.0 
return f 
end 
#----------------------------------- 

class Temperature 
attr_accessor :in_celsius, :in_fahrenheit 

#class metods 
def self.from_celsius(cel) 
    puts "from celsious\n" 
    puts "cel: #{cel}\n" 
    @in_fahrenheit = cel 
    @in_celsius = ctof(cel) 
    puts "==============================\n" 
    return @in_celsius 
end 

def self.in_celsius 
    @in_celsius 
end 


end 


puts "==============================\n" 
puts Temperature.from_celsius(50).in_celsius 
puts Temperature.from_celsius(50).in_fahrenheit 

и Ошибка test.rb:54: in '<main>' : undefined method 'in_celsius' for 122.0:float (noMethod Error) enter code here

+0

Вы, вероятно, хотите использовать модуль для такого рода вещи - только мой 2с –

+0

Grag, вы можете упростить 'FTOC (фр)' в 'Защиту FTOC (FR) (fr-32.0) * (5.0/9.0) end'. Вам не нужно преобразовывать 'fr' в float, потому что' fr-32.0' сделает это, и вам не нужно 'return', потому что Ruby возвращает последний выполненный расчет. То же самое для 'ctof()'. –

+0

@CarySwoveland OP путается в отношении переменных экземпляра класса и переменных экземпляра экземпляров класса. Это нужно сначала исправить. –

ответ

3

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

class Temperature 
    # special method called when creating a new instance 
    def initialize celsius 
    @in_celsius = celsius 
    @in_fahrenheit = celsius * 9/5.0 + 32 
    end 

    def self.from_celsius celsius 
    new celsius # built in method to create an instance, passes argument to initialize 
    end 

    # we defined initialize using celsius, so here we must convert 
    def self.from_fahrenheit fahrenheit 
    new((fahrenheit - 32) * 5/9.0) 
    end 

    private_class_method :new # people must use from_celsius or from_fahrenheit 

    # make instance variables readable outside the class 
    attr_accessor :in_celsius, :in_fahrenheit 
end 

Temperature.from_celsius(50).in_celsius 

Этого код не является совершенным (from_fahrenheit делает избыточное преобразование), но это должно дать вам представление о том, как перестроить свой класс.

+0

новый ((по Фаренгейту - 32) * 5/9.0) Сделал трюк. Мой код отличается от других, но это решило мою проблему ... Большое спасибо! – Grag808

0

from_celsius возвращается поплавок, который не имеет метод in_celsius. Вам нужно это, чтобы вернуть экземпляр температуры, который будет иметь этот метод.

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

+0

Я думаю, что 'return @ in_celsius' бесполезен, поэтому его можно удалить. Поскольку OP имеет строку 'attr_accessor: in_celsius,: in_fahrenheit',' def self.in_celsius..', не имеет смысла, хотя. –

+1

с использованием методов уровня класса возвращающихся экземпляр температуры не будет работать для него либо – bjhaid

+0

@Arup Ракшит Почему вы говорите, что 'attr_accessor: in_celsius,: in_fahrenheit, Защита self.in_celsius' не имеет смысла? – Grag808

0

Давайте посмотрим код puts Temperature.from_celsius(50).in_celsius в деталях:

  1. Призыв к одноплодной методе ::from_celsius из Temperature класса. Это нормально (с некоторыми изменениями), а t возвращает как экземпляр класса Float из-за результата метода #ctof.

  2. Вызвать метод экземпляра #in_celsius объекта, который возвращен из предыдущего метода. Так как это был Float, интерпретатор ищет свой метод экземпляра #in_celsius, не нашел его и выбрасывает исключение NoMethodError.

Как исправить.

Поскольку вы относитесь к ::from_celsius как конструктор Temperature класса, я считаю, что вы раскошеливаться, чтобы передать значение с плавающей в новый метод и возвращает объект. Вы будете иметь класс код следующим образом:

def initialize(value) 
    @in_fahrenheit = cel 
    @in_celsius = ctof(cel) 
end 

def self.from_celsius(cel) 
    puts "from celsious\n" 
    puts "cel: #{cel}\n" 
    temp = Temperature.new(cel) 
    puts "==============================\n" 
    return temp 
end 
+0

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

+0

Спасибо ... за ответ ... Я еще не могу добавить точку для вашего ответ, поскольку у меня пока нет репутации. – Grag808

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