我如何实现Rails之类的东西';在普通Ruby中初始化之前/新建之前?
在Rails中,我们可以定义如下类:我如何实现Rails之类的东西';在普通Ruby中初始化之前/新建之前?,ruby,Ruby,在Rails中,我们可以定义如下类: class Test < ActiveRecord::Base before_initialize :method end 在初始化之前,我试图找出在self.中存储块的位置。我最初尝试在_init_methods之前使用一个实例变量,如,但该实例变量当时不存在于内存中,因此我无法存储或检索它。我不确定在类定义期间如何/在何处存储这些块/过程/符号,稍后将在new中调用这些块/过程/符号 我如何实现这一点?(要么在初始化之前使用,获取一个块/pr
class Test < ActiveRecord::Base
before_initialize :method
end
在初始化之前,我试图找出在self.中存储块的位置。我最初尝试在_init_methods
之前使用一个实例变量,如,但该实例变量当时不存在于内存中,因此我无法存储或检索它。我不确定在类定义期间如何/在何处存储这些块/过程/符号,稍后将在new
中调用这些块/过程/符号
我如何实现这一点?(要么在初始化之前使用,
获取一个块/proc/符号列表,我不介意这一点,只是尝试理解这个概念)对于全面的描述,您可以始终;毕竟,它本身是用“纯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
模块MyCallbacks
def包括在内(klass)
extend(ClassMethods)#我们也没有ActiveSupport::Concern
结束
模块类方法
def初始化\u回调
@回调| |=[]
结束
初始化前定义(&block)
初始化&u回调一种方法是重写Class\new
:
class LameAR
def self.before_initialize(*symbols_or_callables, &block)
@before_init_methods ||= []
@before_init_methods.concat(symbols_or_callables)
@before_init_methods << block if block
nil
end
def self.new(*args, &block)
obj = allocate
@before_init_methods.each do |symbol_or_callable|
if symbol_or_callable.is_a?(Symbol)
obj.public_send(symbol_or_callable)
else
symbol_or_callable.(obj)
end
end
obj.__send__(:initialize, *args, &block)
end
end
class Tester < LameAR
before_initialize :do_stuff
def do_stuff
puts "DOING STUFF!!"
end
end
class-LameAR
初始化前定义自身(*符号或可调用项和块)
@在|init|方法之前|=[]
@before_init_methods.concat(符号或可调用项)
@在初始化方法之前,你的问题有点让人困惑。您所说的“像@这样的实例方法先于\u init\u方法
”是什么意思@before_init_methods
是一个实例变量,而不是一个方法。另外,您所说的“那个实例方法在那个时候不存在于内存中,所以我无法存储或检索它”是什么意思?实例方法一经定义就存在,实例变量一经第一次赋值就存在。事实上,一个实例变量正是解决您的问题的正确方法,所以我有点困惑您为什么如此反对它。@JörgWMittag我已经编辑了这个问题。我的意思是“实例变量”,而不是“实例方法”。实例变量在创建实例之前不存在,因此在类定义期间无法向其添加内容。您可以检查我的答案,该答案使用实例变量没有任何问题。这可以按照我的要求工作,谢谢!虽然我有一个问题,我觉得有些困惑,这就是这里的过程。如果我像这样创建一个procproc=proc.new{puts“Hi!”}
,那么我必须像proc[]
或proc.call()
那样调用它,但是当它在初始化之前通过添加,然后在self.new
中调用时,它可以像proc.(obj)
一样调用。为什么会这样?它仍然是一个proc,但在这种情况下,它可以以通常无法的方式调用。我不理解你的问题<代码>过程。(
只是proc.call()
的语法糖,就像proc[]
是proc的语法糖。[]
或-a+b
是a.-@().+(b)
的语法糖一样。请注意,这与procs无关。它只是语法上的糖,它不在乎接收者是什么。它只会导致发送调用
消息,如果对象响应该消息,则可以,否则会得到命名错误
。您所说的“以通常无法实现的方式调用”是什么意思?顺便说一句:此代码所做的(当然减去中间部分),也正是默认情况下Class#new
所做的。
class LameAR
def self.before_initialize(*symbols_or_callables, &block)
@before_init_methods ||= []
@before_init_methods.concat(symbols_or_callables)
@before_init_methods << block if block
nil
end
def self.new(*args, &block)
obj = allocate
@before_init_methods.each do |symbol_or_callable|
if symbol_or_callable.is_a?(Symbol)
obj.public_send(symbol_or_callable)
else
symbol_or_callable.(obj)
end
end
obj.__send__(:initialize, *args, &block)
end
end
class Tester < LameAR
before_initialize :do_stuff
def do_stuff
puts "DOING STUFF!!"
end
end