【问题标题】:Ruby Instance Methods and VariablesRuby 实例方法和变量
【发布时间】:2014-03-06 23:28:23
【问题描述】:

关于 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

【问题讨论】:

  • 你可能想用一个模块来做这种事情——只是我的 2c
  • Grag,你可以将ftoc(fr)简化为def ftoc(fr) (fr-32.0)*(5.0/9.0) end。您不需要将fr 转换为浮点数,因为fr-32.0 会这样做,并且您不需要return,因为Ruby 返回最后执行的计算。 ctof() 也一样。
  • @CarySwoveland OP 对类实例变量和类实例的实例变量感到困惑。这需要先解决。
  • 好吧..我的主要问题是这里的类实例变量:/

标签: ruby class variables methods instance


【解决方案1】:

from_celsius 返回一个没有 in_celsius 方法的浮点数。您需要它返回一个具有该方法的温度实例。

不得不说你的意图有点令人困惑,除非你对温度类有其他用途,所以很难说你应该走哪条路。

【讨论】:

  • 我觉得return @in_celsius没用,所以可以去掉。由于 OP 有 attr_accessor :in_celsius, :in_fahrenheit 行,def self.in_celsius.. 虽然没有意义。
  • 使用返回温度实例的类级方法对他也不起作用
  • @Arup Rakshit 为什么说attr_accessor :in_celsius, :in_fahrenheit, def self.in_celsius 没有意义?
  • @Arup Rakshit 我对 ruby​​ 很陌生,语法对我来说仍然很混乱。我使用的是attr_accessor :in_celsius,因为需要拨打Temperature.in_celsius 电话。所以我想要实现的是链接我的请求,正如你在puts Temperature.from_celsius(50).in_celsius 中看到的那样
  • @user3290330,我希望温度是一个值和单位,任何转换都会改变值和单位。
【解决方案2】:

您对 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 进行了冗余转换),但它应该让您了解如何重新设计您的类。

【讨论】:

  • new((fahrenheit - 32) * 5 / 9.0) 成功了。我的代码分配不同,但这解决了我的问题......非常感谢!
【解决方案3】:

让我们详细看看代码puts Temperature.from_celsius(50).in_celsius

  1. 调用Temperature 类的单例方法::from_celsius。没关系(有些奇怪),由于#ctof 方法的结果,t 作为Float 类的实例返回。

  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

【讨论】:

  • 嗯..这看起来像是我读到的关于 Ruby 类的东西......我想我知道了 今天晚些时候会试试......
  • 谢谢您的回复...我还不能为您的回答加分,因为我在这里还没有声誉。
猜你喜欢
  • 2011-08-27
  • 2013-05-28
  • 1970-01-01
  • 1970-01-01
  • 2011-02-21
  • 2022-01-18
  • 1970-01-01
  • 2014-09-21
  • 2012-03-07
相关资源
最近更新 更多