alias,别名,顾名思义,就是给某个东西取一个别名。比如我,小时候,穿的破破烂烂,然后发行又长的有点像济公。因此家里的邻居每次都是 济公 济公的叫我。
心累啊。
Ruby 把 alias
提升到了关键字级别。作用也跟它的意思一样。本章节,我们将会讲述和 Ruby alias
关键字有关的以下内容
alias
关键字alias_method
方法- 别名和作用域
- 别名背后的逻辑
Ruby 中的 alias
关键字
一句话解释 Ruby 中的 alias
关键字的作用: 用于给方法和属性定义一个别名。
比如我们有一个类 User
,定义如下
demo.rb
class User def fullname 'John Doe' end end
User
类中的 fullname
对于程序来说并不直观,可能别人想要的是 username
,而 username
实际上就是 fullname
,如果不使用别名,我们一般会如下定义
class User def fullname '简单教程,简单编程' end def username fullname end end
看到多出来的一个方法,我们内心是崩溃的,作为现代语言,Ruby 肯定是不允许这样的存在,因此,它提供了 alias
关键字,用来定义别名。
alias
关键字的语法格式如下
alias [新的名称] [已经存在的方法名或属性名或别名]
比如,我们可以使用 alias
关键来改造上面的代码
class User def fullname '简单教程,简单编程' end alias username fullname end
我们完善下代码,写一个示例运行下
demo.py
class User def fullname '简单教程,简单编程' end alias username fullname end u = User.new p u.fullname p u.username
运行结果如下
[root@www.twle.cn ruby] ruby demo.rb "简单教程,简单编程" "简单教程,简单编程"
另外,alias
还可以对一个别名在创建一个别名,比如
class User def fullname '简单教程,简单编程' end alias username fullname alias name username end u = User.new p u.fullname p u.username p u.name
运行结果如下
[root@www.twle.cn ruby] ruby demo.rb "简单教程,简单编程" "简单教程,简单编程" "简单教程,简单编程"
Ruby alias_method
方法
Ruby 除了可以使用 alias
关键字来定义别名外,还可以使用 alias_method
方法来创建一个别名。
alias_method
方法的原型如下
lias_method(new_name, old_name) → self click to toggle source
参数和关键字顺序与 alias
关键字是一样的。
我们写一小段代码来演示下 alias_method
方法的使用
ruby
class User def fullname '简单教程,简单编程' end alias_method :username, :fullname alias_method 'name',:username end u = User.new p u.fullname p u.username p u.name
运行结果如下
[root@www.twle.cn ruby] ruby demo.rb "简单教程,简单编程" "简单教程,简单编程" "简单教程,简单编程"
如果你比较细心,你会发现 alias_method
方法的参数是要么是一个 symbol ,要么就是一个字符串。这是和使用 alias
关键字最大的不同。如果我们把代码改成下面这样
class User def fullname '简单教程,简单编程' end alias_method username, :fullname alias_method 'name',:username end u = User.new p u.fullname p u.username p u.name
运行就会报错
[root@www.twle.cn ruby] ruby demo.rb demo.rb:6:in `<class:User>': undefined local variable or method `username' for User:Class (NameError) from demo.rb:1:in `<main>'
你也许很疑惑,既然 alias
关键字和 alias_method
方法都共享着相同的行为,那为什么 alias
关键字和 alias_method
方法会同时存在呢,这不是多此一举吗?
哈哈,的确,从表面上看起来的确多此一举,但它们有着本质的区别,它们的区别就是别名的作用域问题
别名和作用域
alias
和 alias_method
是相同的,但又是不同的,如果非要说什么不同,那就是只有一个,就是创建的别名的作用域不同。
准确的来说,alias
和 alias_method
两个不同点在于继承体系中,对旧名字的引用是当前类的下名字还是祖先链中同一个类中定义的名字。
是不是有点难以理解,我们写两个范例来演示下:
demo.rb
class Device def description '简单教程' end def self.alias_description alias describe description end end class Microwave < Device def description '简单教程,简单编程' end alias_description end m = Microwave.new p m.description p m.describe
运行结果如下
[root@www.twle.cn ruby] ruby demo.rb "简单教程,简单编程" "简单教程"
从运行结果中可以看出,alias
关键字的别名,始终是在定义别名时作用域下的属性和名字。
我们在看看 alias_method
方法
class Device def description '简单教程' end def self.alias_description alias_method :describe,:description end end class Microwave < Device def description '简单教程,简单编程' end alias_description end m = Microwave.new p m.description p m.describe
运行结果如下
[root@www.twle.cn ruby] ruby demo.rb "简单教程,简单编程" "简单教程,简单编程"
从运行结果中可以看出,alias_method
方法,别名的使用是当前调用类中的属性名或方法。
别名背后的逻辑
现在,你是不是很好奇 alias
和 alias_method
两个别名的实现。哈哈,不要着急,为了理解它们背后的逻辑,我们得有耐心
我们先回到最开始的那个 alias
关键字的例子
demo.rb
class User def fullname '简单教程,简单编程' end alias username fullname end u = User.new p u.fullname p u.username
在这个范例中, 别名 username
可以看成是重新定义了一个相同实现的方法。
实际上,Ruby 存在一个表 method_entry
中,每个方法都插入到这个表中,我们可以使用该表跟踪程序的所有方法。
但我们使用 def
关键字创建了 fullname
方法时,会在 method_entry
表中插入一个新条目。此条目包含以下信息
:fullname
符号标识符User#fullname
方法User
类名
当调用 alias username fullname
生成一个别名时,也会在 method_entry
表中插入一个新条目。此条目包含以下信息
:usename
符号标识符User#fullname
方法User
类名
这就是 alias
和 alias_method
创建别名的逻辑,是不是很简单。