Ruby变量作用域的类目录结构(补二)

ruby中,类中可以定义类,类中可以定义方法,方法中可以定义方法,但是方法中不能定义类。

在前面写的《Ruby变量作用域的类目录结构》和《Ruby变量作用域的类目录结构(补)》中聊到了前两种情况下变量可视域的问题,关于ruby中可以在方法中定义方法这个细节,我也是今天才知道。

首先,ruby的方法中不能定义常量,所以这里只需要考虑实例变量,普通变量,和类变量三种情况

例子一:在irb中敲入以下代码:

ruby 代码
  1. def meth1      
  2.   var = 1      
  3.   def meth2      
  4.     puts var  #报错,因为var是meth1的局部变量,在meth2中是不可见的      
  5.   end     
  6. end     

meth2这个方法怎么调用,实际上有两种方式,1,meth1::meth2,这种情况下,似乎方法名也变成了某种意义上的命名空间,就像是模块命和类名一样;2:在irb提示符下直接敲入meth2,这里遇到问题一,ruby是怎么处理这个嵌套的def的?为什么meth2变成了irb的一个实例方法?

这两种方法感觉有点儿矛盾的地方,如果meth2位于命名空间meth1下,为什么它又是main的实例方法?反之亦然。

例子二:这次我们把meth1放到一个类中,作为类方法

ruby 代码
  1. class A      
  2.   def meth1      
  3.     var = 1      
  4.     def meth2      
  5.       puts var     
  6.     end     
  7.   end     
  8.   def meth3   
  9.     meth1::meth2  
  10.   end  
  11. end    

我试图通过调用meth3来访问嵌套定义的meth2方法,但是这碰到奇怪的现象,meth2通过meth1::meth2无法访问?总是提示找不到meth2方法,但是在例子1中,基本上一样的定义,通过meth1::meth2却可以调用meth2,非常奇怪。没有看过ruby的源码,那位高人了解,麻烦解释一下。所在在这里只能通过A.new.meth2来调用meth2方法。抛开问题不管,在A.new中调用meth2当然是错的,因为meth2中没有定义局部变量var。

例子三:类似于例子二中的结构,不过这次定义了一个实例变量@var,并且另外定义了一个方法meth3用来打印@var

ruby 代码
  1. class A         
  2.   def meth1         
  3.     @var = 1         
  4.     def meth2         
  5.       puts @var        
  6.     end        
  7.   end        
  8.   def meth3      
  9.     puts @var     
  10.   end     
  11. end     
  12.   
  13. a = A.new     
  14. a.meth1      
  15. a.meth2 => 1      
  16. a.meth3 => 1    

可以看到调用meth2和meth3都可以正确的打印出@var的值

对于类变量的例子,结果和例子三类似。就不多说了。


 

你可能感兴趣的:(Ruby)