`
yueguangyuan
  • 浏览: 337755 次
  • 性别: Icon_minigender_1
  • 来自: 新加坡
社区版块
存档分类
最新评论

[转贴]About ruby’s “open class”

阅读更多
一个有关Ruby的特性,是一个朋友私有博客上写的,我拿过来帮着宣传 :P
至于本文内容,我只能说我在技术方面比较肤浅,很少去研究深层次的东西 :(。
ruby 代码
  1.  
  2. [本文发出的第二天,我不得不对此文进行修改  ]   
  3. Ruby的open class算是是他众多优秀特性中最耀眼的一个,active_support就用这个特性玩出了众多花样,但是今天有人提出了这格特性给ruby带来的安全问题,我在同一个名字空间下写一个跟你的类同名的类覆盖或者添加一个方法,然后在你的类加载之后加载(能出现这个过程的情况估计也很少,有这个条件和功力可以直接改你的source了),岂不是很危险,想想有点道理,怎么才能把某些类的open class给禁了呢?   
  4.   
  5. 1.   
  6.   
  7. 比较简单:   
  8.   
  9. class Test    
  10.      
  11.   def test_method    
  12.     #do somthong...    
  13.   end    
  14.      
  15.   self.freeze    
  16.      
  17. end   
  18. 这样,在class定义结束前(一定要在类末尾,或者干脆在类定义完成后Test.freeze一下)将它freeze一下,就什么都改不了了,搞定。    
  19.   
  20. 这个方案昨天我还以为万无一失,但是turbowolf轻而易举的把freeze flag给去掉了:   
  21.   
  22. require 'dl/struct'    
  23.      
  24. module Internal    
  25.   extend DL::Importable    
  26.      
  27.   typealias "VALUE",nil,nil,nil,"unsigned long"    
  28.   typealias "ID",nil,nil,nil,"unsigned long"    
  29.      
  30.   Basic=["long flags","VALUE klass"]    
  31.   RBasic=struct Basic    
  32.   RObject=struct(Basic+["st_table *iv_tbl"])    
  33.      
  34.   FL_FREEZE=1<<10    
  35. end    
  36.      
  37. class Object    
  38.   def immediate?    
  39.     [Fixnum,Symbol,NilClass,TrueClass,FalseClass].any?{ |klass| klass===self}    
  40.   end    
  41.      
  42.   def unfreeze    
  43.     return self if immediate?    
  44.     Internal::RObject.new(DL::PtrData.new(self.object_id * 2)).flags &= ~ Internal::FL_FREEZE    
  45.     self    
  46.   end    
  47.      
  48. end    
  49.      
  50. class A    
  51.      
  52.   def test_a    
  53.     puts "This is class A"    
  54.   end    
  55.      
  56.   def test_b    
  57.     puts "test_b method in class A"    
  58.   end    
  59.      
  60.   self.freeze    
  61. end    
  62.      
  63.      
  64. class A    
  65.   self.unfreeze    
  66.   def test_a    
  67.       puts "This is class A, modified"    
  68.   end    
  69. end    
  70.      
  71. a=A.new    
  72. a.test_a    
  73. a.test_b   
  74. 所以只能在method_added上下功夫.   
  75. 2.   
  76.   
  77. class Object    
  78.      
  79.   @@hold_methods=Hash.new([])    
  80.      
  81.   def no_instance_method_override    
  82.     class << self    
  83.       def method_added(new_method)    
  84.         if @@hold_methods[self].include?(new_method)    
  85.           raise "You can *NOT* override method \"#{new_method}\" by redefind class #{self}!"    
  86.         else    
  87.           @@hold_methods[self] << new_method    
  88.         end    
  89.       end    
  90.     end    
  91.   end    
  92.      
  93. end   
  94. 保存这段代码,定义class的时候require这个文件,然后作些手脚:   
  95.   
  96. require "...."    
  97.      
  98. class Test    
  99.      
  100.   no_instance_method_override    
  101.      
  102.   def a    
  103.     puts "method a"    
  104.   end    
  105.      
  106. end    
  107.      
  108. class Test    
  109.      
  110.   def a    
  111.     puts "method a modified!"    
  112.   end    
  113.      
  114.   def b    
  115.      puts "method b"    
  116.   end    
  117.      
  118. end   
  119. 这样似乎就达到目的了,你运行的时候会 RuntimeError:You can *NOT* override method “a” by redefind class Test! (RuntimeError),但是只是RuntimeError而已,我rescue一下又会怎样?   
  120.   
  121. require "...."    
  122.      
  123. class Test    
  124.      
  125.   no_instance_method_override    
  126.      
  127.   def a    
  128.     puts "method a"    
  129.   end    
  130.      
  131. end    
  132.      
  133. class Test    
  134.      
  135.   begin    
  136.     def a    
  137.       puts "method a modified!"    
  138.     end    
  139.   rescue    
  140.   end    
  141.      
  142.      
  143.   def b    
  144.      puts "method b"    
  145.   end    
  146.      
  147. end    
  148.      
  149. Test.new.a   
  150. 看到了,a方法还是被修改了,所以raise “Exception”似乎不够狠,来干脆的,exit之 :   
  151.   
  152. class Object    
  153.      
  154.   @@hold_methods=Hash.new([])    
  155.      
  156.   def no_instance_method_override    
  157.     class << self    
  158.       def method_added(new_method)    
  159.         if @@hold_methods[self].include?(new_method)    
  160.           puts "You can *NOT* override method \"#{new_method}\" by redefind class #{self}!"    
  161.           exit(1)    
  162.         else    
  163.           @@hold_methods[self] << new_method    
  164.         end    
  165.       end    
  166.     end    
  167.   end    
  168.      
  169. end   
  170. 这样就好了,不过有点那个…   
  171. 不过由此我发现,thesorensens.org的finalizer是有bug的:   
  172. gem install finalizer之后(上不去rubyforge的去这里下载),   
  173.   
  174. require "rubygems"    
  175. require_gem "finalizer"    
  176. require "finalizer"    
  177.      
  178. class Foo    
  179.    final :bar    
  180.      
  181.    def bar    
  182.      puts 'bar'    
  183.    end    
  184. end    
  185.      
  186. class Bar < Foo    
  187.   begin    
  188.     def bar    
  189.       puts 'mybar'    
  190.     end    
  191.   rescue    
  192.   end    
  193. end    
  194.      
  195. Bar.new.bar   
  196. 你看到了什么?final的method bar被修改了,  所以exit虽然狠了点,但是raise的确是不担当任这个任务。   
分享到:
评论
1 楼 KDr2 2007-02-08  
method_added也被绕过了,可以去我那里看看,不知道有没有别的办法。

相关推荐

    jquery的转贴功能实现

    在本主题中,我们将深入探讨如何利用jQuery实现“转贴”功能,这是一种常见的社交媒体分享功能,允许用户将网页内容轻松分享到各种社交网络。 首先,让我们了解一下jQuery的核心概念。jQuery通过一种简洁的语法提供...

    BFC UBB转贴器

    由于现在流行的转贴工具都是基于浏览器的,转换速度比较慢,还得打开浏览器才能使用(同时受到浏览器版本限制)。 &lt;br&gt; 而这个小程序则完全不依赖于浏览器,以BFC采集器的UBB转换模块为基础,转换速度超快,...

    易语言源码动网转贴.rar

    "动网转贴"这个主题可能指的是在论坛或者社交网络中实现帖子转发或分享的功能。 动网转贴的源码可能涉及到以下几个方面的知识点: 1. **网络通信**:在实现动网转贴功能时,首先需要与服务器进行交互,发送用户的...

    动网转贴.e.rar

    【标题】"动网转贴.e.rar"是一个压缩文件,很可能包含了有关动网论坛或社区的相关资源、数据或用户帖子的备份。动网是中国早期知名的网络论坛软件之一,提供了丰富的社区功能,允许用户发帖、回帖、互动等。这个...

    动易系统的论坛转贴工具

    《动易系统的论坛转贴工具详解与应用》 在互联网信息交流日益频繁的今天,论坛作为用户互动的重要平台,其内容分享与传播的作用不容忽视。动易系统的论坛转贴工具,便是为了解决用户在论坛间便捷分享内容而设计的一...

    Html处理软件、转贴工具(源代码)

    去除Html中的干扰码等(样例中以轻之国度的干扰码为例) 配置文件语法: 方法类型(整数) 最大匹配长度(整数) 字符串1(删除开头) 字符串2(删除结尾) 方法类型: 1:删除单行 2:删除行与行之间的

    易语言动网转贴.rar

    "动网转贴"可能是基于易语言编写的一个功能模块或者工具,用于在论坛或者网站之间转移帖子数据。由于压缩包文件名为“易语言动网转贴.rar”,我们可以推测这可能是一个软件开发资源,包含了一些源代码、教程或者是...

    东度极品论坛转贴工具

    东度极品论坛转贴工具东度极品论坛转贴工具

    电子政务-导电泡棉转贴装置.zip

    在“导电泡棉转贴装置”这个特定的场景下,我们可能是在讨论一种用于电子政务设备或系统中的特殊组件。 导电泡棉是一种具有导电性能的泡沫材料,通常用于电子设备的屏蔽、接地或防静电保护。在电子政务设备中,这种...

    动网转贴.zip易语言项目例子源码下载

    《易语言项目实例——动网转贴》 易语言,作为一种中文编程语言,以其独特的语法和易用性,深受广大编程爱好者尤其是初学者的喜爱。这个名为“动网转贴”的项目,是易语言编程实践中一个典型的例子,它为学习者提供...

    行业分类-设备装置-FPC吸附胶纸转贴组件.zip

    本压缩包文件"行业分类-设备装置-FPC吸附胶纸转贴组件.zip"主要关注的是FPC在实际应用中的一个重要环节——FPC吸附胶纸转贴组件。这个组件在FPC的制造和组装过程中起到关键作用,确保FPC能够稳定地固定在设备上,并...

    转贴一个网络设计的例子

    转贴一个网络设计的例子

    电子功用-导电胶配对模切对半转贴加工方法

    本篇将详细探讨“电子功用-导电胶配对模切对半转贴加工方法”,这是一种高效的生产工艺,旨在提高电子产品的性能和可靠性。 导电胶主要由导电填料(如金属颗粒)、树脂基体和添加剂组成。它的特性在于既能保持良好...

    易语言动网转贴

    "易语言动网转贴"是指使用易语言编写的一段代码或程序,主要用于在动网上实现帖子的转换或者迁移。动网可能是一个论坛或社区平台,转贴功能则是将某个地方的帖子复制到另一个地方,保持其内容完整。 在这个源码中,...

    论坛转贴源代码

    论坛转贴工具提供常的转换追加,转换覆盖,预览贴子,分析超链接,屏蔽文字,图片,超链接,提供查找,替换等功能,HTML版! 支持IE浏览器,360浏览器,搜狗浏览器,火狐浏览器,谷歌chrome浏览器等主流浏览器,无需...

    论坛转贴 v1.0 JS版-源码.zip

    【标题】"论坛转贴 v1.0 JS版-源码.zip" 提供的是一个基于JavaScript的论坛转贴功能的源代码实现。JS版通常指的是使用JavaScript编程语言编写的版本,这表明该软件可能主要用于网页端,利用浏览器的JavaScript引擎...

    行业文档-设计装置-木器、玻璃用贴花纸生产及转贴方法.zip

    《木器、玻璃用贴花纸生产及转贴方法》是一个深入探讨装饰材料工艺的行业文档,主要聚焦于贴花纸在木器和玻璃制品上的应用。这份文档可能包含了从贴花纸的设计、生产到实际转贴过程中的各种技术细节和实践经验。 1....

    [转贴]Symbian编程VC开发环境设置 (方便个人学习用,转载自 rocklys的专栏,转贴请搜索原作者) - waferham的专栏 - CSDNBlog.mht

    [转贴]Symbian编程VC开发环境设置 (方便个人学习用,转载自 rocklys的专栏,转贴请搜索原作者) - waferham的专栏

    uchome2.0+一键转贴插件

    uchome2.0+一键转贴插件 本插件由开源插件网(sns.zhisoo.com)提供。 激励的文章!奋斗的捷径!成功的法则!创业的技巧!奋进的环境! 更重要的是你可以找到与你志趣相同的网友!一起探讨奋斗的目标! 加入我们...

Global site tag (gtag.js) - Google Analytics