`

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

    博客分类:
  • 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的值

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


 

分享到:
评论
1 楼 t284299773 2011-05-05  
你在方法中定义方法就相当于在方法中调用lambda!

相关推荐

    简要解读Ruby面向对象编程中的作用域

    Ruby中不具备嵌套作用域(即在内部作用域,可以看到外部作用域的)的特点,它的作用域是截然分开的,一旦进入一个新的作用域,原先的绑定会被替换为一组新的绑定。 程序会在三个地方关闭前一个作用域,同时打开一个新...

    Ruby中的Proc类及Proc的类方法Proc.new的使用解析

    Proc是对块及其context(局部变量的作用域以及栈框架)进行对象化处理之后得到的过程对象。您可以像使用无名函数那样来使用Proc,但它不会导入局部变量的作用域(可以把动态局部变量用作Proc局部变量)。 在下例中,正...

    关于PHP常见面试题.pdf

    3. PHP中的变量作用域是什么?请说明在PHP中的变量作用域规则。 4. PHP中如何进行错误处理(Error Handling)?请说明在PHP中的错误处理机制。 5. 什么是PHP中的超全局变量(Superglobals)?请列举几个常用的PHP超...

    Linux C程序设计大全

    3.2 变量的作用域和生命期 3.2.1 全局变量 3.2.2 局部变量 3.3 变量的初始值 3.3.1 全局变量的初始值 3.3.2 局部变量的初始值 3.4 与函数有关的优化 3.4.1 函数调用与程序优化 3.4.2 变量存储优化 3.5 编写多文件...

    Ruby语言入门教程

    3.5 标识名和变量的作用域..................................................................................................19 3.6 类库......................................................................

    JavaScript权威指南(第6版)(附源码)

    3.10 变量作用域 第4章 表达式和运算符 4.1 原始表达式 4.2 对象和数组的初始化表达式 4.3 函数定义表达式 4.4 属性访问表达式 4.5 调用表达式 4.6 对象创建表达式 4.7 运算符概述 4.8 算术表达式 4.9 关系表达式 ...

    JavaScript权威指南(第六版) 清晰-完整

    3.10 变量作用域 第4章 表达式和运算符 4.1 原始表达式 4.2 对象和数组的初始化表达式 4.3 函数定义表达式 4.4 属性访问表达式 4.5 调用表达式 4.6 对象创建表达式 4.7 运算符概述 4.8 算术表达式 4.9 关系表达式 ...

    JavaScript权威指南(第6版)(中文版)

    3.10 变量作用域 第4章 表达式和运算符 4.1 原始表达式 4.2 对象和数组的初始化表达式 4.3 函数定义表达式 4.4 属性访问表达式 4.5 调用表达式 4.6 对象创建表达式 4.7 运算符概述 4.8 算术表达式 4.9 关系表达式 ...

    JavaScript权威指南(第6版)

    3.10 变量作用域 第4章 表达式和运算符 4.1 原始表达式 4.2 对象和数组的初始化表达式 4.3 函数定义表达式 4.4 属性访问表达式 4.5 调用表达式 4.6 对象创建表达式 4.7 运算符概述 4.8 算术表达式 4.9 关系表达式 ...

    javaSE代码实例

    6.7.1 局部变量的作用域 89 6.7.2 局部变量的初始化 90 6.8 this预定义对象引用 92 6.9 擅用系统已有的类 94 6.9.1 Java中的Date类 94 6.9.2 Java中的GregorianCalendar类 96 6.9.3 擅用系统已有类的...

    JavaScript权威指南(第6版)

    3.10 变量作用域 56 第4章 表达式和运算符 60 4.1 原始表达式 60 4.2 对象和数组的初始化表达式 61 4.3 函数定义表达式 62 4.4 属性访问表达式 63 4.5 调用表达式 64 4.6 对象创建表达式 64 4.7 运算符概述 65 4.8 ...

    JavaScript权威指南(第6版)中文文字版

    3.10 变量作用域 56 第4章 表达式和运算符 60 4.1 原始表达式 60 4.2 对象和数组的初始化表达式 61 4.3 函数定义表达式 62 4.4 属性访问表达式 63 4.5 调用表达式 64 4.6 对象创建表达式 64 4.7 运算符概述 65 4.8 ...

    augeasproviders:基于Augeas的其他Puppet提供商

    augeasproviders:Puppet的基于Augeas...班级augeasproviders :: instances 此类允许使用类的参数或顶级作用域变量定义此模块提供的类型。 注意:类的参数优先于顶级变量。 将sysctl条目net.ipv4.ip_forward设置为1 :

    Java中的闭包与回调

    “闭包”一词来源于以下两者的结合:要执行的代码块(由于自由变量的存在,相关变量引用没有释放)和为自由变量提供绑定的计算环境(作用域)。在Scheme、CommonLisp、Smalltalk、Groovy、JavaScript、Ruby和Python...

    Scala程序设计(第2版)

    13.6 作用域内私有和作用域内受保护可见性 306 13.7 对可见性的想法 312 13.8 本章回顾与下一章提要 313 第14章 Scala类型系统(I) 314 14.1 参数化类型 315 14.1.1 变异标记 315 14.1.2 类型...

    Grails 技术精解与Web开发实践【源码+样章】----下载不扣分,回帖加1分,欢迎下载,童叟无欺

    与作用域 175 14.2 GSP标签库 175 14.2.1 常用的内置标签 176 14.2.2 开发自定义标签 179 14.3 Grails对Ajax的支持 182 14.4 本章小结 184 第15章 实现Web Service 185 15.1 REST风格的Web Service 185 15.1.1 什么...

    bounty-targets:该项目每小时抓取漏洞赏金平台作用域(例如HackeroneBugcrowdIntigritietc),并将其转储到赏金目标数据存储库中

    设置以下环境变量: SENTRY_DSN :(可选)用于异常跟踪的 API密钥。 SSH_PRIV_KEY :SSH私钥,已授权其写入要向其中推送数据的github项目。 SSH_PUB_KEY :对应于SSH_PRIV_KEY 。 GIT_HOST :要写入的github...

    python 参数列表中的self 显式不等于冗余

    例如,它提供了一种作用域机制,我个人认为比Ruby的@和@@清晰多了,这可能是习惯使然吧,但它确实和C++、Java中的this很相似。 然而,self总是有令我困扰的地方,我以前在这里说过—我曾幻想能在Python3中这些能得以...

    精通正则表达式~~~

    动态作用域及正则匹配效应... 295 匹配修改的特殊变量... 299 qr/…/运算符与regex对象... 303 构建和使用regex对象... 303 探究regex对象... 305 用regex对象提高效率... 306 Match运算符... 306 Match的...

Global site tag (gtag.js) - Google Analytics