ELI5:为什么可以在 class 方法中调用 class 方法而不显式声明 class 本身? (Ruby/Rails)
ELI5: Why can you call class methods within class methods without explicitly stating the class itself? (Ruby/Rails)
抱歉,标题有点令人困惑,但我刚刚发现了一些令人难以置信的东西。当您在 class 方法中调用 class 方法时,您不必在其前面放置 self
以使其执行。我不明白为什么会这样。
例如,假设您有一个具有以下架构的模型 Food
class:
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
或self.new
,只需写new
returns一个新创建的实例。使用 Eigenclass 语法编写方法也会产生相同的结果。这不限于 new
,但它适用于几乎所有适用的 class 方法,例如 create, delete, instance_methods
等
我搜索过为什么会这样,但我不是很明白。请有人解释为什么会发生这种情况以确保我没有出现幻觉?
谢谢!
每当您调用方法时,Ruby 首先检查它是否在 self
上定义。据我所知,只有一个例外——如果你有一个与方法同名的局部变量,它将引用局部变量:
def num; 1; end
num = 2
num # => 2
Class 方法在这方面与实例方法相同。
更容易想到您不能省略自我的情况:
使用 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
抱歉,标题有点令人困惑,但我刚刚发现了一些令人难以置信的东西。当您在 class 方法中调用 class 方法时,您不必在其前面放置 self
以使其执行。我不明白为什么会这样。
例如,假设您有一个具有以下架构的模型 Food
class:
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
或self.new
,只需写new
returns一个新创建的实例。使用 Eigenclass 语法编写方法也会产生相同的结果。这不限于 new
,但它适用于几乎所有适用的 class 方法,例如 create, delete, instance_methods
等
我搜索过为什么会这样,但我不是很明白。请有人解释为什么会发生这种情况以确保我没有出现幻觉?
谢谢!
每当您调用方法时,Ruby 首先检查它是否在 self
上定义。据我所知,只有一个例外——如果你有一个与方法同名的局部变量,它将引用局部变量:
def num; 1; end
num = 2
num # => 2
Class 方法在这方面与实例方法相同。
更容易想到您不能省略自我的情况:
使用 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