Code That Writes Code

6.1 Coding your way to the weekend

6.2 Kernel#eval, Binding#eval

Binding:

Objects of class Binding(类Binding的对象) encapsulate (密封)the execution context at some particular place in the code and retain this context for future use.

如果你想要一段已经执行的代码在今后反复使用,可以用Binding对象封装它。

The variables, methods, value of self, and possibly an iterator block(迭代块) that can be accessed in this context are all retained.

变量,方法,自身的value,甚至迭代块都可以用Binding对象封装储存。

Binding objects can be created using Kernel#binding

eval(string [, filename [,lineno]]) → obj

Evaluates the Ruby expression(s) in string, in the binding's context.

Binding对象的eval方法,可以评估字符串内的Ruby表达式,并返回表达式的值。

If the optional filename and lineno parameters are present, they will be used when reporting syntax errors.

class Myclass
  def my_method
    @x = 1
    binding
  end
end
 
p b = Myclass.new.my_method
p b.eval("@x")
p eval("@x", b)

#结果一样 1

class Anotherclass
  def my_method
    # eval "self", TOPLEVEL_BINDING   #=> main
    eval("xx + yy", TOPLEVEL_BINDING)
  end
end
 
xx = 123
yy = 321
obj = Anotherclass.new
p obj.my_method #=> 444

TOPLEVEL_BINDING: 是预定义常量,表示顶层作用域的Binding对象。

6.24 Strings of Code Vs Blocks

eval只能执行代码字符串,instance_eval和class_eval可以执行代码字符串和block

array = [1,2,3]
x = 'd'
array.instance_eval("self[1] = x")
p array #=> [1, "d", 3]
尽量用block,代码字符串安全性低容易被攻击。同时也难以阅读和修改。

流行的做法是禁止使用eval方法,同时用Dynamic methods和Dynamic Dispatch替代

污染对象

Ruby把外部传入的对象标记为污染对象。Object#taint -> obj.

判断: #tainted? ->true/false

去掉污染 #untaint

谨慎使用安全级别p148页

可以使用proc {}.call 作为洁净室


6.3Hook Method:

Class#inherited是一个实例方法,当一个类被继承时,Ruby会调用这个方法,Class#inherited方法什么也不做,但程序员可以覆写它的行为,像这样的方法称为钩子方法。

inherited(subclass):Callback invoked whenever a subclass of the current class is created.

更多的钩子方法:

Module#included,#prepended,#method_added, #method_removed, #method_undefined (只对实例方法有用),#singleton_method_added...

这种钩子方法写在模块里,用类方法的方式定义:

module M1
  def self.included(othermod)
    puts "m1 was included into #{othermod}"
  end
end
 
class C
  include M1
end
#=>m1 was included into C
 

另外一种方式钩住同一个事件,:#include方法可以覆写 ,但注意写在类C中。

我的理解类C.调用include方法,就是self.include。先是在自身调用覆写的include方法,然后用super关键字调用原始方法。

⚠️ 类方法是不能被继承的只能自己用。

⚠️ 类包含模块后默认是获得实例方法。除非用#extend

module M
  def hello
    puts "world"
  end
end
 
class C
  def self.include(mod)
    puts "Called: C.include(#{mod})"
    super  #因为覆写了include,所以需要用super调用原始的include功能,否则M不会被C包含
  end 
  include(M)
end
 
C.new.hello✅

类方法和钩子方法结合的技巧:P160页。

3-15 《元编程》第6章 3-16 hook method的更多相关文章

  1. 3-8《Ruby元编程》第二章对象模型

    <Ruby元编程> 第二章 对象模型 类定义揭秘inside class definitions: class关键字更像一个作用域操作符,核心作用是可以在里面随时定义方法. [].meth ...

  2. 一道模板元编程题源码解答(replace_type)

    今天有一同学在群上聊到一个比较好玩的题目(本人看书不多,后面才知是<C++模板元编程>第二章里面的一道习题), 我也抱着试一试的态度去完成它, 这道题也体现了c++模板元编程的基础和精髓: ...

  3. 初识C++模板元编程(Template Mega Programming)

    前言:毕设时在开源库上做的程序,但是源码看得很晕(当时导师告诉我这是模板元编程,可以不用太在乎),最近自己造轮子时想学习STL的源码,但也是一样的感觉,大致了解他这么做要干什么,但是不知道里面的机制. ...

  4. 3-11 《Ruby元编程》第4章block块 3-12

    第4章代码块blocks 基础知识 作用域:用代码块携带variables through scopes 通过传递block给instance_eval方法来控制作用域. 把block转换为Proc, ...

  5. C++模板元编程(C++ template metaprogramming)

    实验平台:Win7,VS2013 Community,GCC 4.8.3(在线版) 所谓元编程就是编写直接生成或操纵程序的程序,C++ 模板给 C++ 语言提供了元编程的能力,模板使 C++ 编程变得 ...

  6. 异步编程系列06章 以Task为基础的异步模式(TAP)

    p { display: block; margin: 3px 0 0 0; } --> 写在前面 在学异步,有位园友推荐了<async in C#5.0>,没找到中文版,恰巧也想提 ...

  7. atitit.元编程总结 o99

    atitit.元编程总结 o99.doc 1. 元编程(Metaprogramming) 1 2. 元编程的历史and发展 1 3. 元类型and元数据 1 4. 元编程实现方式 2 4.1. 代码生 ...

  8. C++ 元编程 —— 让编译器帮你写程序

    目录 1 C++ 中的元编程 1.1 什么是元编程 1.2 元编程在 C++ 中的位置 1.3 C++ 元编程的历史 2 元编程的语言支持 2.1 C++ 中的模板类型 2.2 C++ 中的模板参数 ...

  9. ES6中的元编程-Proxy & Reflect

    前言 ES6已经出来好久了,但是工作中比较常用的只有let const声明,通过箭头函数改this指向,使用promise + async 解决异步编程,还有些数据类型方法...所以单独写一篇文章学习 ...

  10. Python类元编程

    类元编程是指在运行时创建或定制类.在Python中,类是一等对象,因此任何时候都可以使用函数创建新类,而无需用class关键字.类装饰器也是函数,不过能够审查.修改,甚至把被装饰的类替换成其他类.元类 ...

随机推荐

  1. [SQL入门级] 这篇咱'薄利多销',记录多一点

    这个系列的博文知识回顾sql知识作的记录,温故而知新.上一篇内容达不到知识分享的层级被移出园子首页,对不住各位看官,内容简单了些.下面咱就记录多一些的基础知识,薄利多销: 控制用户权限 • 创建用户 ...

  2. pycharm中内看内建函数的定义

    鼠标方法在内建函数上,Ctrl+B,看内建函数的定义 如果想要看内置函数的具体实现细节,可以到python的lib目录下C:\Python27\Lib\,或者python的官网上 如果要看非内建的函数 ...

  3. outlook还原初始设置

    找到outlook的安装地址: C:\Program Files\Microsoft Office\Office15 进入命令行界面 WIN+R ->cmd cd C:\Program File ...

  4. Java实现Sybase数据库连接

    Java实现Sybase数据库连接 需要的jar包:jconn4.jar: Java代码: /** * @Title: getConnSybase * @Description: * @param * ...

  5. "/var/lib/mysql/mysql.sock"不存在解决办法

    今天再次遇到mysql.sock问题, 下面是我的三种解决方案. 解决办法: 1./etc/my.cnf,至少增加/修改一行(前提是您find到了这个mysql.sock是在tmp下) [mysql] ...

  6. 20145333茹翔 Exp8 Web基础

    20145333茹翔 Exp8 Web基础 实验问题回答 (1)什么是表单 表单是一个包含表单元素的区域,表单元素是允许用户在表单中(比如:文本域.下拉列表.单选框.复选框等等)输入信息的元素,表单在 ...

  7. SVC(STM32)

    这两个都是 system level service,有什么区别呢?…… 手册上说 SVC 这个指令是同步的,而 PendSV 是异步的,请问是什么意思呢?…… 高手路过尽请留言啊

  8. Visual Leak Detector简明使用教程

    Visual Leak Detector是一款内存泄漏检测软件,主要的作用就是检测可能或者是存在内存泄露的地方,具体的功能的话,可以百度下,今天主要简单介绍下怎么使用 首先下载Visual Leak ...

  9. Python3基础 tuple 通过拆分元素 把元组的数据删除

             Python : 3.7.0          OS : Ubuntu 18.04.1 LTS         IDE : PyCharm 2018.2.4       Conda ...

  10. Ansible 入门指南 - 学习总结

    概述 这周在工作中需要去修改 nginx 的配置,发现了同事在使用 ansible 管理者系统几乎所有的配置,从数据库的安装.nginx 的安装及配置.于是这周研究起了 ansible 的基础用法.回 ...