gpt4 book ai didi

ruby - 我如何在纯 Ruby 中实现 Rails 的 before_initialize/before_new 之类的东西?

转载 作者:数据小太阳 更新时间:2023-10-29 07:51:38 25 4
gpt4 key购买 nike

在 Rails 中我们可以定义一个类:

class Test < ActiveRecord::Base
before_initialize :method
end

并且当调用Test.new时,method()将在实例上被调用。我正在尝试了解更多关于 Ruby 和类方法的信息,但我在尝试用普通 Ruby 实现它时遇到了麻烦。

这是我目前所拥有的:

class LameAR
def self.before_initialize(*args, &block)
# somehow store the symbols or block to be called on init
end

def new(*args)
## Call methods/blocks here
super(*args)
end
end

class Tester < LameAR
before_initialize :do_stuff

def do_stuff
puts "DOING STUFF!!"
end
end

我正在尝试找出将 block 存储在 self.before_initialize 中的位置。我最初尝试了一个像 @before_init_methods 这样的实例变量,但是那个实例变量当时不存在于内存中,所以我无法存储或检索它。我不确定在类定义期间如何/在哪里存储这些 block /过程/符号,以便稍后在 new 中调用。

我该如何实现? (要么让 before_initialize 获取一个 block /proc/符号列表,我现在不介意,只是想理解这个概念)

最佳答案

全面的描述可以随时check the Rails source ;毕竟,它本身是用“纯 Ruby”实现的。 (但它会处理很多边缘情况,因此不适合快速概览。)

快速版本是:

module MyCallbacks
def self.included(klass)
klass.extend(ClassMethods) # we don't have ActiveSupport::Concern either
end

module ClassMethods
def initialize_callbacks
@callbacks ||= []
end

def before_initialize(&block)
initialize_callbacks << block
end
end

def initialize(*)
self.class.initialize_callbacks.each do |callback|
instance_eval(&callback)
end

super
end
end

class Tester
include MyCallbacks
before_initialize { puts "hello world" }
end

Tester.new

留给读者:

  • 争论
  • 按名称调用方法
  • 继承
  • 回调中止调用并提供返回值
  • “环绕”包装原始调用的回调
  • 条件回调(:if/:unless)
  • 子类有选择地覆盖/跳过回调
  • 在序列的其他地方插入新的回调

...但省略所有这些是 [希望] 使此实现更容易实现的原因。

关于ruby - 我如何在纯 Ruby 中实现 Rails 的 before_initialize/before_new 之类的东西?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51122655/

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