是否可以在Ruby中创建(或模拟)关键字?
我刚开始学习
Ruby,但我已经有了很多想法,可以利用它作为OOPL的独特性.标题中恰当地描述了我的第一个:是否可以在Ruby中创建(或模拟)关键字?我在repl中玩了一下,发现了一些带有别名的有趣的东西.
例如,如果您尝试通过说明对关键字类别名 alias :magic :class 它似乎工作,因为它输出零.但是,它只是别名Object#类方法;我的猜测是没有办法为关键字设置别名,因为关键字不是常量,很可能硬编码到解释器本身. (但是这个小实验确实有一个有趣的结果.通常,如果没有显式的自我标识符,就不能调用Object#类方法;只需在repl中键入类就会产生语法错误,因为它会与关键字类混淆.但是,通过别名Object#类方法,解释器不再混淆,因此您可以使用没有标识符的别名.非常漂亮.) 现在,由于我对Ruby的了解有限,我相信一种模拟关键字的方法,例如,类似于这样的事情: # in some file Magic.rb module Magic def self.type # do something to evaluate the given block as a class definition yield if block_given? end end Magic.type Awesome do def initialize;end def who_am_i? puts "I'm Awesome!" end end x = Awesome.new # desired output: #<Awesome:0x1234abc> x.who_am_i? # desired output: "I'm Awesome!" 但这比我希望的更加丑陋.有什么想法吗? 编辑:经过一些修补和谷歌搜索后,我发现了我认为是一个很好的解决方案,利用匿名类实例化,块和Object#const_set: def type aName,&block Object.const_set(aName,Class.new(Array,&block)) end type :AwesomeArray do def intialize puts "Initialized." end def magic puts "DO ALL THE MAGICKS!" end end x = AwesomeArray.new # --> #<Awesome:0x12335abc> puts x.is_a? AwesomeArray # --> true puts x.is_a? Array # --> true puts x.is_a? Object # --> true x.magic # --> "DO ALL THE MAGICKS!" x |= [1,2,3] # --> [1,3] 用户定义的类型方法有效地模仿了class关键字.或者,您可以使用字符串而不是符号调用type,并在将其传递给Class.new时向aName添加to_sym调用.或两者兼顾! def type aSymbol,&block Object.const_set(aSymbol,&block)) end def type_str aString,&block type aString.to_sym,&block end 现在,作为一个Ruby n00b(r00b?),有什么遗传或传统上不好这样做?例如,它可能在某种程度上是非常昂贵或危险的吗? 解决方法
TL; DR:如果你没有充分的理由这样做,请不要
顺便说一句,你不能模拟关键字.它们内置于解析器中.所有你能做的就是你想出的元编程黑客……但是: 并不是说效率低得多: user system total real type method: 0.000000 0.000000 0.000000 ( 0.000034) class keyword: 0.000000 0.000000 0.000000 ( 0.000030) 这只是糟糕的形式.为什么用无用的方法使全局命名空间变得混乱,这使得你的代码更难以被其他人阅读?代码读取的内容远远超过编写代码.不要让别人或你自己在事情上变得更难. 这也有一些范围的问题,将在稍后的路上回到字节.例: 2.0.0p0 :001 > def type aName,&block 2.0.0p0 :002?> Object.const_set(aName,&block)) 2.0.0p0 :003?> end => nil 2.0.0p0 :004 > a = 'hi' => "hi" 2.0.0p0 :005 > type :Hi1 do 2.0.0p0 :006 > puts a 2.0.0p0 :007?> end hi => Hi1 2.0.0p0 :008 > class Hi2 2.0.0p0 :009?> puts a 2.0.0p0 :010?> end NameError: undefined local variable or method `a' for Hi2:Class from (irb):9:in `<class:Hi2>' from (irb):8 块范围与类范围不同.此外,这不会正确处理类变量(尽管你不应该没有很好的理由使用Ruby的类变量……): 2.0.0p0 :012 > type :T1 do 2.0.0p0 :013 > @@t1test = 'hi' 2.0.0p0 :014?> end (irb):13: warning: class variable access from toplevel => T1 2.0.0p0 :015 > T1.class_variables => [:@@t1test] 2.0.0p0 :018 > class T2 2.0.0p0 :019?> @@t2test = 'bork' 2.0.0p0 :020?> end => "bork" 2.0.0p0 :021 > Object.class_variables => [:@@t1test] 2.0.0p0 :022 > T2.class_variables => [:@@t2test,:@@t1test] 如您所见,您的块表单将类变量泄漏给每个类(来自Object).不太好. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |