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,变成了死循环。

(0)

相关推荐

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

    我最近考虑了很多元编程(Metaprogramming)的问题,并希望看到更多这方面技术的例子和讲解.无论好坏,元编程已经进入Ruby社区,并成为完成各种任务和简化代码的标准方式.既然找不到这类资源,我准备抛砖引玉写一些通用Ruby技术的文章.这些内容可能对从其它语言转向Ruby或者还没有体验到Ruby元编程乐趣的程序员非常有用. 1. 使用单例类 Use the singleton-class 许多操作单个对象的方法是基于操作其单例类(singleton class),并且这样可以使元编程更简

  • ruby元编程实际使用实例

    很喜欢ruby元编程,puppet和chef用到了很多ruby的语言特性,来定义一个新的部署语言. 分享几个在实际项目中用到的场景,能力有限,如果有更优方案,请留言给我:) rpc接口模板化--使用eval.alias.defind_method require 'rack/rpc' class Server < Rack::RPC::Server def hello_world "Hello, world!" end rpc 'hello_world' => :hello

  • Ruby和元编程之万物皆为对象

    开篇 空即是色,色即是空. 空空色色,色色空空,在Ruby语言中,万物皆为对象. Ruby是一个面向对象的语言(Object Oriented Language),面向对象的概念比其他语言要贯彻的坚定很多. Ruby中不存在Java中原始类型数据和对象类型数据之分.大部分Ruby中的的东东都是对象. 所以,想要掌握Ruby和Ruby的元编程,对象就是第一门必修功课.本回就着重研究一下Ruby中的对象. Ruby中的对象 如果你从其他面向对象的语言转来,一提到得到一个对象你可能会想到建立一个类,然

  • Ruby元编程基础学习笔记整理

    笔记一: 代码中包含变量,类和方法,统称为语言构建(language construct). # test.rb class Greeting def initialize(text) @text = text end def welcome @text end end my_obj = Greeting.new("hello") puts my_obj.class puts my_obj.class.instance_methods(false) #false means not i

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

    我最近读了些文章(比如这篇),宣传在 Ruby 里使用 method_missing 的. 很多人都与 method_missing 干柴烈火,但在并没有小心处理彼此之间的关系.所以,我想来探讨一下这个问题: ** 我该怎么用 method_missing ** 什么时候该抵挡 method_missing 的诱惑 首先,永远不要在还没花时间考虑你用得够不够好之前,就向 method_missing 的魅力屈服.你知道,在日常生活中,很少会让你以为的那样亟需 method_missing: 日常

  • Ruby元编程的一些值得注意的地方

    避免无限循环的元编程. 写一个函数库时不要使核心类混乱(不要使用 monkey patch). 代码块形式最好用于字符串插值形式.         当你使用字符串插值形式,总是提供 __FILE__ 和 __LINE__,使得你的回溯有意义. class_eval 'def use_relative_model_naming?; true; end', __FILE__, __LINE__ define_method 最好用 class_eval{ def ... } 当使用 class_eva

  • Ruby元编程小结

    今天被问到此类问题,以前总是觉得这个是比较宽泛的一个概念,自己即使是用过这些特性,但却一直不知道这叫"元编程" 直到今天被人问起的时候,方才顿悟一些,随后便在网上和自己的平实用的一些元编程做个小总结. 原来所谓的Ruby中的元编程,是可以在运行时动态的操作语言结构(如类.模块.实例变量等)的技术.你甚至于可以在不用重启的情况下,在运行时直接键入一段新的Ruby代码,并执行他. Ruby的元编程,也具有"利用代码来编写代码"的作用.例如,常见的attr_accesso

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

    method_missing是Ruby元编程(metaprogramming)常用的手法.基本思想是通过实现调用不存在的方法,以便进行回调.典型的例子是:ActiveRecord的动态查找(dynamic finder).例如:我们有email属性那么就可以调用User.find_by_email('joe@example.com'),虽然, ActiveRecord::Base并没有一个叫做find_by_email的方法. respond_to? 并不如method_missing出名,常用

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

    我们知道顶级域,定义域的self是啥? 复制代码 代码如下: puts self    #main puts self.class #Object 我们知道当一个方法被调用的时候,如果没有对象接受,默认就是self,如: 复制代码 代码如下: def tell_me_who     puts self end tell_me_who  #main 方法调用是这样的步骤,先查找当前对象的所在类的实例方法存在方法与否,如果存在,调用方法,如果不存在则查看superclass,直到 BasicObje

  • 详解C++元编程之Parser Combinator

    引子 前不久在CppCon上看到一个Talk:[constexpr All the things](https://www.youtube.com/watch?v=PJwd4JLYJJY),这个演讲技术令我非常震惊,在编译期解析json字符串,进而提出了编译期构造正则表达式(编译期构建FSM),现场掌声一片,而背后依靠的是C++强大的constexpr特性,从而大大提高了编译期计算威力. 早在C++11的时候就有constexpr特性,那时候约束比较多,只能有一条return语句,能做的事情只有

  • 详解Java高并发编程之AtomicReference

    目录 一.AtomicReference 基本使用 1.1.使用 synchronized 保证线程安全性 二.了解 AtomicReference 2.1.使用 AtomicReference 保证线程安全性 2.2.AtomicReference 源码解析 2.2.1.get and set 2.2.2.lazySet 方法 2.2.3.getAndSet 方法 2.2.4.compareAndSet 方法 2.2.5.weakCompareAndSet 方法 一.AtomicReferen

  • Python网络编程之HTTP客户端模块urllib与urllib3

    一.urllib 概述: urllib是Python中请求url连接的官方标准库,就是你安装了python,这个库就已经可以直接使用了,基本上涵盖了基础的网络请求功能.在Python2中主要为urllib和urllib2,在Python3中整合成了urllib. Python3.x中将urllib2合并到了urllib,之后此包分成了以下四个模块: urllib.request: 它是最基本的http请求模块,用来模拟发送请求 urllib.error: 异常处理模块,如果出现错误可以捕获这些异

  • python编程之requests在网络请求中添加cookies参数方法详解

    哎,好久没有学习爬虫了,现在想要重新拾起来.发现之前学习爬虫有些粗糙,竟然连requests中添加cookies都没有掌握,惭愧.废话不宜多,直接上内容. 我们平时使用requests获取网络内容很简单,几行代码搞定了,例如: import requests res=requests.get("https://cloud.flyme.cn/browser/index.jsp") print res.content 你没有看错,真的只有三行代码.但是简单归简单,问题还是不少的. 首先,这

  • Python编程之Re模块下的函数介绍

    re模块下的函数 compile(pattern):创建模式对象 import re pat=re.compile('A') m=pat.search('CBA') #等价于 re.search('A','CBA') print m <_sre.SRE_Match object at 0x9d690c8> #匹配到了,返回MatchObject(True) m=pat.search('CBD') print m None #没有匹配到,返回None(False) search(pattern,

  • Linux网络编程之UDP Socket程序示例

    在网络传输协议中,TCP协议提供的是一种可靠的,复杂的,面向连接的数据流(SOCK_STREAM)传输服务,它通过三段式握手过程建立连接.TCP有一种"重传确认"机制,即接收端收到数据后要发出一个肯定确认的信号,发送端如果收到接收端肯定确认的信号,就会继续发送其他的数据,如果没有,它就会重新发送. 相对而言,UDP协议则是一种无连接的,不可靠的数据报(SOCK_DGRAM)传输服务.使用UDP套接口不用建立连接,服务端在调用socket()生成一个套接字并调用bind()绑定端口后就可

  • 解析Java编程之Synchronized锁住的对象

    图片上传 密码修改为  synchronized是java中用于同步的关键字,一般我们通过Synchronized锁住一个对象,来进行线程同步.我们需要了解在程序执行过程中,synchronized锁住的到底是哪个对象,否则我们在多线程的程序就有可能出现问题. 看下面的代码,我们定义了一个静态变量n,在run方法中,我们使n增加10,然后在main方法中,我们开辟了100个线程,来执行n增加的操作,如果线程没有并发执行,那么n最后的值应该为1000,显然下面的程序执行完结果不是1000,因为我们

随机推荐