在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
本节书摘来自华章出版社《Effective Ruby:改善Ruby程序的48条建议》一书中的第2章,第2.4节,作者 [美]彼得 J.琼斯(Peter J. Jones),更多章节内容可以访问云栖社区“华章计算机”公众号查看 第9条:提防Ruby最棘手的解析说到命名规则,Ruby给了我们很大的自由。肃然不像Lisp那样的语言一样自由,但Ruby允许我们在方法末尾使用三个字母数字以外的符号:“?”、“!”和“=”。三个字符中的两个具有纯粹的美感,而另一个在Ruby中有特殊的含义。 如你所知,以问号结束的方法名既不会改变任何事情,也不会使Ruby对它特殊对待。这仅仅是一个为Ruby程序员所接受的命名惯例,以此来说明方法将返回一个布尔值。(要知道什么是Ruby中的布尔值,请参见第1条。)这个命名惯例并不是强制的,并且以“?”结尾的方法仍然可以返回你想要的任何类型的值。感叹号也是类似的,如果有所不同,也只是模糊一点。感叹号常常意味着方法会改变接收者,也可以是对你的示警,表示存在潜在的有害行为。这两种情况都是Ruby程序员指南中不提倡的。以等号结尾的方法则完全不同。 即使从技术上讲“=”是方法名的一部分,Ruby却允许我们在等号和方法名的其他部分之间输入空格。这看似是变量赋值,但实质上仅仅是一个普通的方法调用。当你加上括号并去掉空格时你会更清楚地看到这一点。 你可能不曾亲手定义过这些setter方法,但你一定间接地定义过。因为Ruby有一些帮助方法能帮我们做这个事情。attr_writer和attr_accessor都像之前的例子一样定义了类似value=这样的setter方法。这样的迂回可能会让你有点困惑,这也是我提起它们的原因。只要你记住这些帮助方法做的事情以及接下来的建议,任何困难都不是问题。 把initialize方法体中的内容当作对counter=方法的调用也不是毫无道理,这也是很多人所假设的。但这当然是不对的,那只是个简单的变量赋值呀。initialize方法创建了一个新的局部变量counter,并将其赋值为0,然后又在作用域结束的时候丢弃了对这个变量的引用。当你仔细思考,会发现这显然不是我们想做的。(如果你像第5条建议的那样启用了警告,Ruby将会在出现这个错误时提醒你。) 通过使用self作为接收者,Ruby将正确地解析你的代码并调用counter=这个setter方法,而非创建一个新的变量。你可能会想,如果在调用方法时在等号和方法名的其他部分间不加等号,并用括号包住参数也许可以避免使用self(即,counter=(0)),然而事与愿违,这是无效的。我们在这里被迫显式地使用self作为接收者,但这导致了另一个问题。 显然,full方法中的self是冗余的。由于没有调用setter方法,你可以安全地移除self并依靠那些简单的解析规则。当Ruby遇到类似f?irst或last的标识符时,它会检查当前作用域中是否存在同名变量。如果不存在,它会把这个标识符作为方法名再次查找。在本例中,对于Name类里的两个属性,Ruby通过早先的attr_accessor找到了它们的getter方法。这里有另一个版本的full方法,与之前的方法做了相同的事情,但去除了噪音: 到此为止,你应该对setter方法的特殊性确信无疑了。如果不想碰到些惊喜,记得调用时指定一个接收者。但是千万别因此让它愚弄了你,并不是所有方法都需要接收者,尤其是在实例方法中调用时。对于每个其他类型的方法,如果没有显式指定方法接收者,Ruby将自动使用self作为接收者。 |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论