2015-08-28 3 views
4

У меня есть следующий код:Scope и «я» ключевое слово

def self.ftoc(temp_in_fahrenheit) 
    (temp_in_fahrenheit - 32) * 5.0/9.0 
end 

def self.ctof(temp_in_celcius) 
    (temp_in_celcius * 9.0/5.0) + 32 
end 

def calculate_temperatures 
    @f = Temperature.ctof(@c) if (@f == nil && @c != nil) 
    @c = Temperature.ftoc(@f) if (@c == nil && @f != nil) 
end 

Это прекрасно работает. Однако, если я изменил код

def calculate_temperatures 
    @f = self.ctof(@c) if (@f == nil && @c != nil) 
    @c = self.ftoc(@f) if (@c == nil && @f != nil) 
end 

Я получаю ошибку

undefined method 'ftoc' for #<Temperature:0x000000025486a0 @f=50> 

я бы подумал, что «я», как экземпляр класса температуры, будет иметь возможность использовать CTOF/ftoc, но это не так. Может ли кто-нибудь помочь мне понять, что мне не хватает?

Большое спасибо.

ответ

2

Внутри метод self является экземпляром из Temperature. Внутри class это экземпляр Class, имеющий имя Temperature.

Попробуйте это:

class Temperature 
    puts "Inside class: self is #{self}, Temperature is #{Temperature}" 

    def meth 
    puts "Inside method: self is #{self}, Temperature is #{Temperature}" 
    end 
end 

Temperature.new.meth 

Тем не менее, внутри class, те эквивалентны:

class Temperature 
    def self.meth ; end 
    def Temperature.meth ; end 
end 

Но внутри method, self становится в переменной экземпляра, в то время как постоянное Temperature, экземпляр Class, все еще относится к тому, что вы ожидали.

Чтобы отнестись к классу из метода внутреннего экземпляра, можно использовать self.class. Тем не менее, внутри метода экземпляра, те эквивалентны:

class Temperature 
    def meth 
    Temperature.ctof(...) 
    self.class.ctof(...) 
    end 
end 
+0

Спасибо! Я собираюсь ответить на этот вопрос, потому что мое замешательство связано с тем, что «я» меняется в зависимости от того, где он используется, и это помогло мне понять этот момент. – mikeappell

1

ftoc и ctof методы класса, потому что вы указали self ключевое слово в объявлении. В другой руке calculate_temperatures - это метод экземпляра.

, что вы должны сделать для того, чтобы получить доступ к методам класса в методах экземпляра используется self.class:

def calculate_temperatures 
    @f = self.class.ctof(@c) if (@f == nil && @c != nil) 
    @c = self.class.ftoc(@f) if (@c == nil && @f != nil) 
end 
+0

Спасибо за ответ. Есть ли причина, по которой self.class.ctof лучше/предпочтительнее, чем Temperature.ctof или Temperature :: ctof? – mikeappell

+1

Да, использование 'self.class' облегчит использование полиморфизма. Кроме того, легче прочитать код и понять, что метод класса, который вы вызываете, определяется в той же иерархии классов, что и вызывающий метод экземпляра. –

+0

Полезно знать, еще раз спасибо. – mikeappell

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