Ruby-否则工作方法会在类中定义一次

时间:2014-03-11 22:00:30

标签: ruby

我正在玩一个“流利的计算器”练习,我遇到了一个我不明白的问题。如果我在irb(第一个代码块)中独立定义一些测试方法,它们可以工作,但是如果我在类中定义它们,我开始得到NoM​​ethodError,即使有关方法和它们返回的内容看起来都相同。在类中定义这些方法会导致它们表现不同的是什么?

独立定义:

1.9.3p484 :097 >   def one
1.9.3p484 :098?>       if self.is_a? String
1.9.3p484 :099?>           instance_eval "#{self} 1"
1.9.3p484 :100?>         else
1.9.3p484 :101 >             1
1.9.3p484 :102?>         end
1.9.3p484 :103?>     end
 => nil 
1.9.3p484 :104 >   def two
1.9.3p484 :105?>       if self.is_a? String
1.9.3p484 :106?>           instance_eval "#{self} 2"
1.9.3p484 :107?>         else
1.9.3p484 :108 >             2
1.9.3p484 :109?>         end
1.9.3p484 :110?>     end
 => nil 
1.9.3p484 :111 >   def plus
1.9.3p484 :112?>       "#{self} +"
1.9.3p484 :113?>     end 
 => nil 
1.9.3p484 :114 > one.class
 => Fixnum 
1.9.3p484 :115 > two.class
 => Fixnum 
1.9.3p484 :116 > plus.class
 => String 
1.9.3p484 :117 > one.plus.two
 => 3 

在类Calc中定义:

1.9.3p484 :024 > class Calc
1.9.3p484 :025?>     
1.9.3p484 :026 >       def one
1.9.3p484 :027?>         if self.is_a? String
1.9.3p484 :028?>             instance_eval "#{self} 1"
1.9.3p484 :029?>           else
1.9.3p484 :030 >               1
1.9.3p484 :031?>           end
1.9.3p484 :032?>       end
1.9.3p484 :033?>     
1.9.3p484 :034 >       def two
1.9.3p484 :035?>         if self.is_a? String
1.9.3p484 :036?>             instance_eval "#{self} 2"
1.9.3p484 :037?>           else
1.9.3p484 :038 >               2
1.9.3p484 :039?>           end
1.9.3p484 :040?>       end
1.9.3p484 :041?>     
1.9.3p484 :042 >       def plus
1.9.3p484 :043?>         "#{self} +"
1.9.3p484 :044?>       end      
1.9.3p484 :045?>   end
 => nil 
1.9.3p484 :046 > Calc.new.one.class
 => Fixnum 
1.9.3p484 :047 > Calc.new.two.class
 => Fixnum 
1.9.3p484 :048 > Calc.new.plus.class
 => String 
1.9.3p484 :049 > Calc.new.one.plus.two
NoMethodError: undefined method `plus' for 1:Fixnum
    from (irb):49
    from /Users/miles/.rvm/rubies/ruby-1.9.3-p484/bin/irb:12:in `<main>'

3 个答案:

答案 0 :(得分:2)

在第一个示例中,您在全局命名空间中声明“加号”,因此它也适用于Fixnum。在第二个示例中,它在类中声明,因此它仅适用于该类的对象。但是,Fixnum与您的班级不同。

调用Calc.new.one时,您将获得Fixnum(因为one)。所以你不能打电话给.plus

答案 1 :(得分:2)

提示:查看self.class

在全局命名空间中定义它时,实际上是在Object类上定义方法,所有其他对象都从该类继承,因此FixnumString继承新方法。将它们放入课程后,FixnumString不再定义这些方法。

答案 2 :(得分:0)

在您使用句点(点.)的每一点上,您应该考虑返回的内容:

Calc.new =一个新的Calc对象(通过在Calc上调用新方法返回Calc个对象)

Calc.new.one = one对象上调用的Calc方法(返回1对象的Fixnum

Calc.new.one.plus = plus上调用的1方法 - &gt; plus1对象上未定义Fixnum方法,因此您出现undefined method错误。