`
Anleb
  • 浏览: 31982 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

ruby元编程之 method_missing 一个细节

阅读更多
我们知道顶级域,定义域的self是啥?
puts self    #main
puts self.class #Object


我们知道当一个方法被调用的时候,如果没有对象接受,默认就是self,如:
def tell_me_who
    puts self
end
tell_me_who  #main



方法调用是这样的步骤,先查找当前对象的所在类的实例方法存在方法与否,如果存在,调用方法,如果不存在则查看superclass,直到 BasicObject都没找到对于方法的话,就会调用Kernel的method_missing()方法,并且报错,如:
Error:test.rb:8: undefine: undefined local variable or method `ask' for main:Object (NameError)


注意报错的信息,我们可以发现,当我们调用一个不存在的变量的时候,也是会追溯到Kernel的method_missing方法的,这里要注意咯。

验证:

puts self    #main
puts self.class #Object
def self.method_missing(name,*arg)
    puts "#{name} is not exist!"
end
puts ask   #ask is not exist!



一个案例导致BUG:

def self.method_missing(name,*arg)
    1.times do 
        puts method_name=name
    end
    puts "#{method_name} is not exist!"
end

ask #变量或者方法


意图:让任何未定义的变量或者方法,都打印一次
可是,这是一个死循环?看出问题了吗
ask被执行,可是没有定义ask,就会转到method_missing,
method_name在times的block中,出了作用域了,所以又会执行method_missing,变成了死循环。

2
3
分享到:
评论
2 楼 Anleb 2012-08-01  
tenderuser 写道
方法和变量都是对象,表示上也没有什么特殊的地方。。 。处理应该也是一样的把


有点区别,对于方法不说了,很简单,obj.method,obj是接受者,方法method发送消息告诉obj。

但是  顶级域调用 变量的时候,如果不加 接受者 如: ask (随意一个变量),默认是self,也就是main,系统会认为是一个 接受者是main的ask方法。


实例变量也是变量,他存在于对象中,但是实例变量没法从外部调用,只能依靠attr_accessor或者属性方法调用,实例方法存在于类中,就这点区别。
1 楼 tenderuser 2012-07-31  
方法和变量都是对象,表示上也没有什么特殊的地方。。 。处理应该也是一样的把

相关推荐

    ruby元编程之method_missing的一个使用细节

    主要介绍了ruby元编程之method_missing的一个使用细节,本文介绍在使用method_missing时造成死循环的一个现象,需要的朋友可以参考下

    Ruby元编程之梦中情人method_missing方法详解

    主要介绍了Ruby元编程之梦中情人method_missing方法详解,本文讲解了我该怎么用 method_missing 、方法代理、define_method、什么时候用 method_missing、元方法等内容,需要的朋友可以参考下

    Ruby元编程pdf

    `method_missing`是Ruby的一个特殊方法,当调用一个未定义的方法时,系统会自动调用它,允许开发者处理未知的方法调用。 3. **变量**:Ruby的变量可以在运行时被重新定义。全局变量、实例变量和类变量都可以动态...

    ruby元编程之创建自己的动态方法

    method_missing是Ruby元编程(metaprogramming)常用的手法。基本思想是通过实现调用不存在的方法,以便进行回调。典型的例子是:ActiveRecord的动态查找(dynamic finder)。例如:我们有email属性那么就可以调用...

    intro_to_metaprogramming:Ruby元编程简介

    我不知道是否一定要同意这一点,但是Ruby中的元编程是一个非常强大的工具,可以导致习惯性的Ruby。 对于Rails开发人员来说,即使您没有直接使用Ruby元编程,也可以通过使用Rails获得收益。 该研讨会由( 为“ 。 ...

    脚本编程之: ruby_bcyy_jb51.net

    标题中的“脚本编程之:ruby_bcyy_jb51.net”显然指的是一个关于Ruby编程语言的教程或者文章集合,可能是在jb51.net这个网站上发布或收集的。Ruby是一种面向对象的、动态类型的脚本语言,由日本人松本行弘(Yukihiro ...

    Ruby 编程

    Ruby编程是一种高级、面向对象的脚本语言,以其简洁、优雅的语法和强大的元编程能力而受到程序员的喜爱。Ruby的设计理念强调代码的可读性和自然表达性,这使得它成为初学者入门的理想选择。"Ruby 编程"的资源特别...

    Ruby元编程技术详解(Ruby Metaprogramming techniques)

    在Ruby中,每个对象都有一个与之关联的单例类,这个类只包含该对象的实例方法。通过`class ; self; end`可以访问到对象的单例类,这对于在运行时添加或修改对象的方法非常有用。`Kernel#singleton_class`方法可以...

    Metaprogramming ruby

    其中,`method_missing`是一个特殊的方法,用于处理未定义的方法调用,是实现动态行为的重要工具。 3. **符号到方法转换(Symbol#to_proc)**:Ruby允许将符号转换为块(Proc对象),这样可以更简洁地编写代码。...

    Metaprogramming Ruby(Second Edition)

    《Metaprogramming Ruby(Second Edition)》是Ruby编程语言领域的一本经典著作,由Peter Eberhardt和Paolo Perrotta共同撰写。这本书详细介绍了如何利用Ruby的强大元编程特性来提升代码的灵活性、可扩展性和简洁性。...

    ruby官方chm文档

    理解如何使用`eval`、`class_eval`和`instance_eval`,以及如何利用`send`和`method_missing`进行消息传递,是提升Ruby编程技巧的关键。 《ruby23.chm》文档可能是整个Ruby语言的综合指南,可能包含前面几个文档的...

    MetaProgramming-Play:重写 Ruby 注入方法以了解元编程

    第 10 周:创客学院在 Ruby 中玩转元编程挑战: 使用method_missing重新定义对象在询问has_unknown_attribute时的Reacthas_unknown_attribute 。 使用define_method创建Ruby 内置attr_accessor方法的布尔版本。代码...

    ruby中文教程,从基础到深入的让你学习ruby

    Ruby的Gem库是其生态系统的一大亮点,提供大量的第三方库和框架,如Rails(一个流行的Web开发框架)、Sinatra(轻量级Web框架)和Rspec(测试框架)。通过`gem install`命令,你可以轻松安装和管理这些库。 对于Web...

    ist的matlab代码-rails_lecture_lesson_xhtml_builder:创建一个Ruby类以使用块函数和Ruby元编程

    创建一个Ruby类,以使用块函数和Ruby元编程来创建(X) HTML文档。 生成的类应能够按以下方式使用,并且还应符合此处随附的RSpec规范。 笔记 覆盖method_missing方法,并使用它来拦截对不存在的方法的调用。 每个不...

    Ruby语言教程大纲.zipRuby语言教程大纲.zip

    5. **元编程**:Ruby的元编程能力强大,允许在运行时修改自身。这部分会讲解如何使用`class_eval`、`instance_eval`、`method_missing`等特性。 6. **标准库和Gem**:Ruby有一个丰富的标准库,如Net::HTTP用于网络...

    ruby中文文档 chm版

    Ruby的元编程能力是其独特之处,它允许在运行时修改代码的行为。这通过反射(reflection)和动态方法定义(method_missing)等机制实现,极大地增强了代码的灵活性和可扩展性。 `chm`文件是一种Windows平台下的帮助...

    Ruby程序设计

    6. **继承(Inheritance)与多态(Polymorphism)**:Ruby支持单一继承,一个类只能从一个父类派生,但可以通过`include`或`prepend`来实现多重继承的效果。多态性体现在子类可以重写父类的方法,或者通过鸭子类型...

Global site tag (gtag.js) - Google Analytics