ruby-on-rails - ELI5:为什么你可以在类方法中调用类方法而不明确说明类本身?(红宝石/导轨)
问题描述
抱歉,标题有点令人困惑,但我刚刚发现了一些令人难以置信的东西。当你在类方法中调用类方法时,你不必self
在它前面放一个来让它执行。我不明白为什么会这样。
例如,假设您有一个Food
具有以下架构的模型类:
create_table "foods", force: :cascade do |t|
t.string "name", null: false
t.string "food_type", null: false
t.datetime "expiration_date", null: false
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end
class Food < ApplicationRecord
def self.output_new
new(name: 'marshmallow', food_type: 'snack')
end
end
而不是写Food.new
or self.new
,简单地写new
返回一个新创建的实例。使用 Eigenclass 语法编写方法也会产生相同的结果。这不仅限于,new
但它几乎适用于所有适用的类方法create, delete, instance_methods
,如 等。
我已经搜索过为什么会这样,但我真的不明白。有人可以解释为什么会发生这种情况以确保我没有产生幻觉吗?
谢谢!
解决方案
每当你调用一个方法时,Ruby 首先检查它是否定义在self
. 我知道只有一个例外——如果你有一个与方法同名的局部变量,它将引用局部变量:
def num; 1; end
num = 2
num # => 2
在这方面,类方法与实例方法相同。
更容易想到不能省略 self 的情况:
例如,当使用 setter 方法
self.foo = "bar"
时,它是必需的,因为 Ruby 需要知道您不只是尝试设置局部变量(就像foo = "bar"
那样):class Test attr_writer :foo def initialize self.foo = 1 # calls the setter method foo = 2 # creates a local variable end end
当局部变量和方法(两者具有相同名称)之间存在歧义并且您想要调用该方法时:
class Foo def self.a; 1; end def self.b a = 2 a # references local variable self.a # calls method a() # can also call the method by writing out parens (removes ambiguity) end end
什么时候
self
不是你希望它在那个范围内的。class Foo def self; a; 1 end a # obviously doesn't work, it isn't defined here Foo.a # works
当方法名称与保留字相同时(例如
class
)def class_name class.name # syntax error, it thinks you want to define a class self.class.name # works end
推荐阅读
- c# - 根据条件更改列表框项的颜色
- reactjs - 如何正确使用 react-router-dom No match 404?
- python - 在 Python 脚本中使用正则表达式
- asp.net - 在 ASP.NET Core 中结合使用 cookie 和令牌身份验证
- java - Simba][SpannerJDBCDriver](100300) 来自服务器的错误消息:INVALID_ARGUMENT:不支持位置参数
- java - 被覆盖的方法不会抛出异常(java 中的实现)
- javascript - 如何更快地加载谷歌地图图钉
- c# - 获取场景中所有按钮的名称并存储它们?
- proxy - HTTPoison sock5 代理
- typescript - 为什么我不能在 TS 中优化对象键?