ruby中,类中可以定义类,类中可以定义方法,方法中可以定义方法,但是方法中不能定义类。
在前面写的《Ruby变量作用域的类目录结构》和《Ruby变量作用域的类目录结构(补)》中聊到了前两种情况下变量可视域的问题,关于ruby中可以在方法中定义方法这个细节,我也是今天才知道。
首先,ruby的方法中不能定义常量,所以这里只需要考虑实例变量,普通变量,和类变量三种情况
例子一:在irb中敲入以下代码:
- def meth1
- var = 1
- def meth2
- puts var #报错,因为var是meth1的局部变量,在meth2中是不可见的
- end
- end
meth2这个方法怎么调用,实际上有两种方式,1,meth1::meth2,这种情况下,似乎方法名也变成了某种意义上的命名空间,就像是模块命和类名一样;2:在irb提示符下直接敲入meth2,这里遇到问题一,ruby是怎么处理这个嵌套的def的?为什么meth2变成了irb的一个实例方法?
这两种方法感觉有点儿矛盾的地方,如果meth2位于命名空间meth1下,为什么它又是main的实例方法?反之亦然。
例子二:这次我们把meth1放到一个类中,作为类方法
- class A
- def meth1
- var = 1
- def meth2
- puts var
- end
- end
- def meth3
- meth1::meth2
- end
- end
我试图通过调用meth3来访问嵌套定义的meth2方法,但是这碰到奇怪的现象,meth2通过meth1::meth2无法访问?总是提示找不到meth2方法,但是在例子1中,基本上一样的定义,通过meth1::meth2却可以调用meth2,非常奇怪。没有看过ruby的源码,那位高人了解,麻烦解释一下。所在在这里只能通过A.new.meth2来调用meth2方法。抛开问题不管,在A.new中调用meth2当然是错的,因为meth2中没有定义局部变量var。
例子三:类似于例子二中的结构,不过这次定义了一个实例变量@var,并且另外定义了一个方法meth3用来打印@var
- class A
- def meth1
- @var = 1
- def meth2
- puts @var
- end
- end
- def meth3
- puts @var
- end
- end
- a = A.new
- a.meth1
- a.meth2 => 1
- a.meth3 => 1
可以看到调用meth2和meth3都可以正确的打印出@var的值
对于类变量的例子,结果和例子三类似。就不多说了。