我刚刚开始学习 Ruby,但对于如何利用它作为 OOPL 的独特性,我已经有了一些重要的想法。我的第一个标题恰当地描述了:是否可以在 Ruby 中创建(或模拟)关键字?我在 repl 中玩了一下,发现了一些关于别名的有趣事情。
例如,如果您尝试通过说
alias :magic :class
它似乎有效,因为它输出nil
. 但是,它只是别名Object#class
方法;我的猜测是没有办法给关键字起别名,因为关键字不是常量,很可能硬编码到解释器本身中。
(不过,这个小实验确实有一个有趣的结果。通常,如果没有显式标识符,您不能调用该Object#class
方法;仅输入repl 会产生语法错误,因为它与关键字混淆了。但是,通过给方法起别名,解释器不再感到困惑,因此您可以使用没有标识符的别名。非常漂亮。)self
class
class
Object#class
现在,由于我对 Ruby 的了解有限,我相信模拟关键字的一种方法是,class
例如,执行以下操作:
# 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, 2, 3]
用户定义的type
方法有效地模仿了class
关键字。或者,您可以type
使用字符串而不是符号进行调用,并在将to_sym
调用aName
传递给Class.new
. 或者两者都做!
def type aSymbol, &block
Object.const_set(aSymbol, Class.new(Array, &block))
end
def type_str aString, &block
type aString.to_sym, &block
end
现在,作为一个 Ruby n00b(r00b?),这样做有什么继承或传统上的坏处吗?例如,在某些方面它可能真的很昂贵或危险吗?