Ruby 在initialize之外声明实例变量

Ruby 在initialize之外声明实例变量,ruby,class,Ruby,Class,我试图把摄氏温度转换成华氏温度,反之亦然。如下所示,实例变量@temperature分别在方法celsius=和fahrenheit=中定义 class Temperature def self.ctof(temp) (temp * 9 / 5.0) + 32 end def self.ftoc(temp) (temp - 32) * (5 / 9.0) end def initialize(options) if options[:f]

我试图把摄氏温度转换成华氏温度,反之亦然。如下所示,实例变量
@temperature
分别在方法
celsius=
fahrenheit=
中定义

class Temperature
  def self.ctof(temp)
    (temp * 9 / 5.0) + 32
  end

  def self.ftoc(temp)
    (temp - 32) * (5 / 9.0)
  end

  def initialize(options)
    if options[:f]
      self.fahrenheit = options[:f]
    else
      self.celsius = options[:c]
    end
  end

  def fahrenheit=(temp)
    @temperature = self.class.ftoc(temp)
  end

  def celsius=(temp)
    @temperature = temp
  end

  def in_fahrenheit
    self.class.ctof(@temperature)
  end

  def in_celsius
    @temperature
  end
end

这让我感到困惑,因为我从未见过在initialize方法之外定义的实例变量。我希望有人能帮助我理解这里发生了什么。

当您调用
温度。新建(c:0)
,这将设置
摄氏度=
访问器,该访问器将实例变量
@Temperature
(始终以摄氏度为单位)设置为
0


调用
Temperature.new(f:32)
时,将设置
fahrenheit=
访问器,该访问器将实例变量
@Temperature
设置为
Temperature.ftoc(32)
,或
0.0

在本例中,以摄氏度调用
只会返回
@temperature
,或
0

在华氏温度下调用
将返回
温度.ctof(0)
,或
32.0


在构造函数外部定义实例变量并没有什么神奇之处。关键是它是一个在所有实例方法中都可用的变量。

初始化
之外设置实例变量是非常好的。这正是二传手所做的。您可能已经知道–当调用
attr\u accessor:foo
时,它会为实例变量
@foo
创建一个getter
foo
和一个setter
foo=
,即两个方法等效于:

def foo
  @foo
end

def foo=(value)
  @foo = value
end
在您的代码中,
在摄氏度
摄氏度=
中,就是这样:
@temperature
的getter和setter

但是你的代码看起来确实有点复杂。我想这是因为
温度
必须同时处理华氏温度和摄氏温度。您可以通过为每个温度标度提供单独的类来简化它:

class Celsius
  attr_reader :value

  def initialize(value)
    @value = value
  end

  def to_celsius
    self
  end

  def to_fahrenheit
    Fahrenheit.new((value * 9 / 5.0) + 32)
  end
end

class Fahrenheit
  attr_reader :value

  def initialize(value)
    @value = value
  end

  def to_celsius
    Celsius.new((value - 32) * (5 / 9.0))
  end

  def to_fahrenheit
    self
  end
end
现在,每个类都有一个实例变量
@value
,该变量在
initialize
中设置

temperature = Celsius.new(0)
#=> #<Celsius:0x007fb83d8b33a8 @value=0>

temperature.to_fahrenheit
#=> #<Fahrenheit:0x007fb83d8b3128 @value=32.0>
温度=摄氏度。新建(0)
#=> #
温度。至华氏度
#=> #

你所说的方法
摄氏
华氏
是什么意思?我在你的代码中找不到它们。与你的问题无关,但你的转换容易出现浮点不准确:
Temperature.new(f:10)。in_fahrenheit
返回
9.999999999996
实例变量未声明或定义。就像Ruby中的所有其他变量一样,当它们被赋值时,它们神奇地出现了。