gpt4 book ai didi

ruby-on-rails - 如何在子类中包含行为?

转载 作者:行者123 更新时间:2023-12-05 02:54:30 25 4
gpt4 key购买 nike

我担心 included block 。在此示例中,它设置了一个类实例变量。

require 'active_support/concern'

module Mod1
extend ActiveSupport::Concern

included do
p "#{self}: included Mod1"
@foo = "foo is set"
end

class_methods do
def foo
@foo
end
end
end

如果我包含它,我将获得方法 foo 并设置包含的变量。

class Parent
include Mod1
end

p Parent.foo # "Parent: included Mod1" "foo is set"

但是如果我从 Parent 派生子类,我继承方法 foo,但包含的 block 不会运行。

class Subclass < Parent
end

p Subclass.foo # nil

即使我包含模块,包含的 block 也不会运行。我期望是因为 Subclass.include?(Mod1) 是真的。

class Subclass < Parent
include Mod1
end

p Subclass.foo # nil
p Subclass.include?(Mod1) # true

如何编写关注点,使其 included block 甚至在子类上运行?

最佳答案

ActiveSupport::Concern#included实际上只是 Module#included 的语法糖所以它只会在模块包含在父类中时触发。您要找的 Hook 是Class#inherited每当创建当前类的子类时都会调用它。

require 'active_support/concern'

module Mod1
extend ActiveSupport::Concern

included do
set_foo!
end

class_methods do
def foo
@foo
end

def set_foo!
p "Setting foo"
@foo = "foo is set"
end

def inherited(child_class)
puts "inherited!"
child_class.set_foo!
end
end
end

class Parent
include Mod1
end

class Subclass < Parent; end
require 'minitest/autorun'
class Mod1Test < Minitest::Test
def test_class_ivar_set_in_subclass
assert_equal("foo is set", Subclass.foo) # passes
end
end
"Setting foo"
inherited!
"Setting foo"
Run options: --seed 35149

# Running:

.

Finished in 0.000999s, 1000.7185 runs/s, 1000.7185 assertions/s.
1 runs, 1 assertions, 0 failures, 0 errors, 0 skips

关于ruby-on-rails - 如何在子类中包含行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61785774/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com