深入理解alias, alias_method和alias_method_chain

对于alias, alias_method, alias_method_chain的深入理解是有益的,因为rails3的源码里很多地方使用了alias_method_chain的魔法。 有人评论说alias_method_chain使用的过多不好,具体怎么不好,是后话了,这篇文章集中在理解这3个方法上面。

如果想转载本文,请注明出处,谢谢!请尊重别人的劳动成果,为构建丰富web原创内容做贡献!


1. alias
   Ruby里的关键字,用于定义方法或者全局变量的别名。 例子:
   class A
     def m1
       puts "m1"
     end
     alias m2 m1
    end
=> nil
a = A.new
=> #<A:0xb7ef5234>
 a.m1
m1
=> nil
a.m2
m1
=> nil

在使用的时候,注意原有的方法名在最后位置,用空格分开。

2. alias_method
作用和alias差不多,是Module的一个私有实例方法,只能用于给方法起别名,并且参数只能是字符串或者符号(alias后面跟的直接是方法名,不是字符串也不是符号)。例子:
class B
  def b
    p "b"
  end
  alias_method :c, :b
end
=> B
b = B.new
=> #<B:0xb7ee75bc>
b.c
"b"
=> nil
b.b
"b"
=> nil
注意,alias_method的参数必须是字符串或者是符号,并且用逗号分隔。

3. alias_method_chain
是ActiveSupport的一个公有实例方法。同样接受两个参数,可以是符号,也可以是字符串,但要注意一下第1个参数才是原始方法(alias_method的第2个参数是原始方法)。例子:
class A
  def m1
    puts 'm1'
  end
  def m1_with_m2
    puts "do something befor m1"
    m1_without_m2
    puts "do something after m2"
  end
  alias_method_chain :m1, :m2
end
=> A
a = A.new
=> #<A:0xb7bd9820>
a.m1
do something befor m1
m1
do something after m2
=> nil

上面的代码用alias或者alias_method也能完成:
class A  
  def m1  
    puts 'm1'  
  end
  alias m1_without_m2 m1  
  def m1_with_m2  
    puts 'do something else'  
    m1_without_m2  
  end  
  alias m1 m1_with_m2  
end

那么其原理也一目了然了:
a = A.new
a.m1
当调用m1的时候, m1_with_m2会执行,  在puts "do something befor m1"之后,执行m1_without_m2,这个时候是执行了真正的m1方法。 这样就形成了一个类似于AOP的行为。
也可以说,对外把m1方法隐藏起来了,对类外部,实际上把m1_with_m2改头换面已经成为了另一个方法,只是我们不知道而已,因为它还叫m1.

再来看看alias_method_chain的源码:
def alias_method_chain(target, feature) 
  # Strip out punctuation on predicates or bang methods since 
  # e.g. target?_without_feature is not a valid method name. 
  aliased_target, punctuation = target.to_s.sub(/([?!=])$/, ''), $1 
  yield(aliased_target, punctuation) if block_given?      
  with_method, without_method = "#{aliased_target}_with_#{feature}#{punctuation}", "#{aliased_target}_without_#{feature}#{punctuation}" 
  alias_method without_method, target 
  alias_method target, with_method       
  case 
    when public_method_defined?(without_method) 
      public target 
    when protected_method_defined?(without_method) 
      protected target 
    when private_method_defined?(without_method) 
      private target 
  end 
end
一个道理。

更实际的例子:
在一些rails比较老的系统里,搜索功能的日期选择可能会用到date_select,这个方法会生成类似于这样的页面元素:
search_form[start_from(1i)]年
search_form[start_from(2i)]月
search_form[start_from(3i)]日
把这样的参数传回去,就无法查询到对应的日期。这个时候我们需要在后台得到查询条件之后来处理日期,比如:
get_conditions 这个方法假如是得到页面查询条件的,它返回一个数组,这个时候我们可以定义:

def get_conditions_with_handle_date
  puts "你可以在get_conditions方法执行前干点别的,如果你愿意"
  get_conditions_without_handle_date
  puts "get_conditions执行完了,我们可以在其后干点别的,比如说处理日期"
  conditions.reject!{|condition|condition[0] =~ /\([1-3]i\)/}   # 把条件数组里的1i,2i,3i之类的去掉。
  conditions << ["? <= #{@model.table_name}.created_at", @search.start_from] if @search.start_from  #给搜索对象里添加正确的查询日期条件
  conditions << ["#{@model.table_name}.created_at < ?", @search.end_to + 1.day] if @search.end_to   #给搜索对象里添加正确的查询日期条件
end
  #然后实施魔法
  alias_method_chain :get_conditions, :handle_date

这样我们就搞定了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/304092.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql数据库的安装和配置文件_MySQL 数据库安装与配置详解

目录一、概述MySQL 版本&#xff1a;5.7.17客户端工具&#xff1a;NavicatforMySQL** 二、MySQL 安装**安装条件&#xff1a;如果 Windows Server 2003 在安装.net framework4.0 安装过程中报错&#xff1a; net framework 4.0 安装时提示产生阻滞问题:运行安装程序前&#xff…

Magicodes.IE Excel合并行数据导入教程

说明Magicodes.IE.Excel目前已支持合并行单元格导入&#xff0c;如本篇教程所示。安装包Magicodes.IE.ExcelInstall-PackageMagicodes.IE.Excel添加Dto参考示例代码如下所示&#xff1a;public class MergeRowsImportDto {[ImporterHeader(Name "学号")]public long…

2010.7.27 OnDraw与OnPaint有什么区别

引用&#xff1a;http://wenku.baidu.com/view/bc9b1c661ed9ad51f01df2ab.html OnPaint是WM_PAINT消息的消息处理函数&#xff0c;在OnPaint中调用OnDraw&#xff0c;一般来说&#xff0c;用户自己的绘图代码应放在OnDraw中。 OnPaint()是CWnd的类成员&#xff0c;负责响应WM_P…

D轮融资1亿美金,6亿美金估值,3位计算机学霸如何带领海归团队创造业内神话?!

顺为资本在创始合伙人雷军及许达来的带领下成功领投了51Talk、丁香园、爱奇艺、一起作业等超级公司有近20家公司估值超过10亿美元如今顺为资本为何愿意投资这家公司&#xff1f;酷家乐6年破6亿美金的公司估值17年全年营收超3亿有着设计师300万这家以家居云设计为核心的创业公司…

linux下mysql案例_Linux下安装MySQL多实例

环境说明&#xff1a;Centos 6.6 64位mysql 使用最新版本5.7.16版本这里安装两个MySQL实例&#xff0c;分别使用3306/3307端口号目录结构&#xff1a;/data/mysql/mysql3306/data/mysql/mysql3306/data/data/mysql/mysql3307/log/data/mysql/mysql3306/tmp执行命令&#xff1a;…

Navicat

作为Oracle, MySQL, Sqlite, PostgreSQL的统一客户端&#xff0c;Navicat无疑是最方便简洁的&#xff0c;而且界面非常友好。导入导出支持的格式也很全。 在连Oracle的时候&#xff0c;会报错说字符集不支持。只要手工指定OCI就好&#xff0c;方法如下&#xff1a; 在OCI libra…

分布式链路追踪框架的基本实现原理

目录分布式追踪分布式系统分布式追踪分布式追踪有什么用呢什么是分布式追踪Dapper分布式追踪系统的实现跟踪树和 spanJaeger 和 OpenTracingOpenTracing 数据模型Span 格式TraceOpenTracingJaeger 结构SpanOpenTracing API分布式追踪什么是分布式追踪分布式系统当我们使用 Goog…

mysql外键约束创建及删除_MySQL中的外键的创建,约束和删除

一、外键的创建语法一&#xff1a;后续添加方法alter table 表名 add constraint 约束名 foreign key(当前表中约束的字段) references 主表表名(要约束的字段名);alter table student add constraint fk_class_student foreign key(cls_id) class(cls_id) on update cascade o…

不爱读书怎么办?用这个新奇的方法,熟知137亿年来的地球通史

今天&#xff0c;小木为模友们挑选的小荐货&#xff1a;《地球通史墙书》第一次接触《地球通史》墙书的时候&#xff0c;虽然“地球通史”的概念非常吸引我&#xff0c;但“墙书”的叫法怎么听都像是一个噱头&#xff0c;所以小木一直有些莫名的排斥&#xff0c;直到在小天把试…

测试驱动开发简介

本文节选自《测试驱动的面向对象软件开发》 第1章第4节“测试驱动开发简介” TDD核心的循环是&#xff1a;写一个测试&#xff1b;写一些代码让测试通过&#xff1b;重构代码&#xff0c;使被测试特征的实现尽可能简单。重复这个过程&#xff0c;如图1-1所示。 图1-1基本TDD循环…

在 .NET 中使用 Flurl 高效处理Http请求

简介官方介绍&#xff0c;Flurl是一个现代的&#xff0c;流利的&#xff0c;支持异步的&#xff0c;可测试的&#xff0c;可移植的&#xff0c;URL增强和Http客户端组件。Url构建现在有一个登录的接口&#xff0c;地址如下&#xff1a;https://www.some-api.com/login?nameLee…

java jdbc 删除_java使用jdbc实现各种类型添加删除修改数据

项目描述上次为大家分享了使用jdbc实现各种类型查询数据&#xff0c;这次为大家分享使用jdbc实现各种类型添加、删除、修改数据运行环境jdk8tomcat7mysql项目技术(必填)jdbcdao层数据库文件DROP TABLE IF EXISTS class;CREATE TABLE class (id int(11) NOT NULL auto_increment…

图像还可以这样玩!如何用波的算法处理图像

我对图像处理一直很感兴趣&#xff0c;曾经写过好几篇博客。前几天读到一篇文章&#xff0c;它提到图像其实是一种波&#xff0c;可以用波的算法处理图像。我顿时有一种醍醐灌顶的感觉&#xff0c;从没想到这两个领域是相关的&#xff0c;图像还可以这样玩&#xff01;下面我就…

[存档]CxServer的项目周期管理

2019独角兽企业重金招聘Python工程师标准>>> 主题&#xff1a;大学生创新性实验计划 项目周期管理 作者&#xff1a;宋志民备注&#xff1a;本文为《 基于CxServer的大学生科学研究项目管理实践探索》的一部分 内容&#xff1a; 一般情况下大学生科研计划的种类较多…

C# 在PC上的通过蓝牙(bluetooth)发送数据到手机

概述在PC端用.NET开发一个蓝牙下载的程序。实现在PC上查找周围的蓝牙设备&#xff08;主要是手机&#xff09;&#xff0c;并将PC上的文件通过蓝牙传输到手机上。目前我采用的是OpenNETCF.Net.Bluetooth&#xff0c;能够正常发现周围的蓝牙设备&#xff0c;手机也能够正常进行蓝…

新浪股票接口 java_新浪股票接口Android SDK(非官方)

新浪股票接口AndroidSDK昨天想到一个点子&#xff0c;需要访问股票行情。于是在网上搜了一下免费的股市行情的接口。发现新浪股票的数据接口比较稳定&#xff0c;于是就用它了。网上对于新浪股票的数据接口介绍比较详细&#xff0c;并且实现也很简单&#xff0c;所以花了一下午…

VC++的dll中接收消息

LRESULT CALLBACK MessageWinProc(HWND hwnd, // handle to windowUINT uMsg, // message identifierWPARAM wParam, // first message parameterLPARAM lParam // second message parameter)//用于处理消息窗口接收到的消息{switch(uMsg){case WM_CLOSE:DestroyW…

在职场中,长得漂亮真的有用吗?

非常有用。下面五张图&#xff0c;每张图介绍一个研究&#xff0c;都可以从一个侧面回答问题。01 企业对求职者的颜值有多看重&#xff1f;这张图来自两位学者对国内某网站超过100万份招聘广告的分析结果。总的来看&#xff0c;有7.7%的企业会对应聘者的外貌提出要求&#xff0…

TIOBE 3月榜单:新功能将加入,C语言仍高居榜首

喜欢就关注我们吧&#xff01;TIOBE 公布了 2021 年 3 月的编程语言排行榜。本月 TIOBE 指数没有什么有趣的变化。因此&#xff0c;TIOBE CEO Paul Jansen 表示&#xff0c;其打算透露一些近期将加入至榜单中的新功能。第一个问题涉及到一个 bug 修复。由于使用了复杂的算法&am…

java jdk win10安装_Java 安装 JDK WIN10

JDK的全称是Java SE Development Kit它的官方网站只要用Goole搜索下即可找到&#xff0c;官方提供JDK8、11、12的下载入口。我们点击Java SE Development Kit 8进入下载。我们下载的版本是jdk-8u91-windows-x64.exe安装过程按导向默认安装&#xff0c;中途什么选项都不改。安装…