我正在开发一个基于类似现有应用程序的新Rails应用程序。在我的旧应用程序中,我有优惠券类,这与我的新应用程序中的Ticket非常相似。我想重用优惠券中的所有代码,但使用新的类名。
由于重构在Rails中很麻烦,我想知道是否有办法在Ruby中为类创建别名(类似于属性和方法的别名)。
答案 0 :(得分:84)
类在Ruby中没有名称。它们只是分配给变量的对象,就像任何其他对象一样。如果要通过其他变量引用类,请将其分配给另一个变量:
Foo = String
答案 1 :(得分:15)
:
class Coupon
#...
end
# add this line of code to make alias for class names
# option1. if you haven't defined a "Ticket" class:
Ticket = Coupon
# option2. if Ticket has been defined, you have to redefine it:
Object.send :remove_const, "Ticket"
const_set "Ticket", Coupon
“任何以大写字母开头的引用,包括类和模块的名称,都是常量” - << metaprogramming ruby>&gt ;, page38,Constant section
答案 2 :(得分:5)
任何人来到这里寻找如何为一个rails模型类别名以获得一个新名称:
我能够简单地执行Foo = Bar
,但必须将Foo
放入其自己的模型文件中,这样我才能获得未初始化的常量错误。 e.g。
# models/foo.rb
Foo = Bar
此外,您可能会发现在has_many
,has_one
等关联中尝试使用别名的奇怪现象。我发现您通常可以通过使用根命名空间(或适当的命名空间)来解决这些问题。取决于你的模型的结构)确保Rails试图自动加载正确的常量:
has_many :foo, class_name: '::Foo'
答案 3 :(得分:2)
我同意warhog,或多或少 - 但我会从优惠券类中继承门票 - 如果您需要进行任何数据修改,那么您可以将代码放入门票类
答案 4 :(得分:2)
你必须小心这一点,因为如果你的类经历任何状态变化(添加函数,更改常量,类变量等),你的类在时别名的状态实例化后不会反映您班级中的更新更改。
为了在不牺牲可读性的情况下避免腕管,您可以在别名对象而不是实际类中存储lambda。当然,lambda包含类,但这可以确保您的别名将调用类的最新版本。
我把它放在我的supermanpatches.rb
rails初始值设定项中(config/initializers/
内)‡
LAP = lambda { LosAngelesParcel }
现在你可以使用LAP[]
来调用它,并且会加载你的类的新版本。 (允许您创建实例,例如,l = LAP[].new
)
‡运行一次&然后通过你的应用程序普遍存在,可以在任何地方调用,就像一个全局变量,但“只读”,可以这么说。