gpt4 book ai didi

ruby-on-rails - 将代码注入(inject) ruby​​ 状态机?

转载 作者:数据小太阳 更新时间:2023-10-29 08:13:11 24 4
gpt4 key购买 nike

我想对 pluginaweek 状态机 (https://github.com/pluginaweek/state_machine) 进行猴子修补,这样我就可以将代码从混合模块注入(inject)到状态机中。有谁知道如何在状态机中定义一个新方法来做到这一点?或者,也许有更好的方法来完成我想要完成的事情?

假设,

class Artifact < ActiveRecord::Base
include Provisionable # << This module makes the magic method 'provision',
# << below, available

state_machine :machine_state, :initial => :s_initial do
# ...
provision(:param1, :param2, :param3) # << The Question: how to define
# << this in the Provisionable mixin
# << module, below
...
end
...
end

module Provisionable
#
# << provision() is supposed to inject the desired code into the state machine:
#
def provision

# << Code sample to be injected begins here:
event :parameterize do
transition :s_unprovisioned => :s_initial
end
before_transition :s_unprovisioned => :s_initial do |artifact, transition|
transition.args.each_pair do |param, value|
# etc...
end
end
# >> Code to be injected ends here.

end
end

对于那些购买状态机的人,我强烈推荐这个。

谢谢!

[稍后添加:]我想出了一个解决方案,希望对其他人有所帮助。我没有混入模块,而是猴子修补了 state_machine 以添加实例方法来注入(inject)代码。

StateMachine::Machine.class_eval do
def inject_provisioning()

event :start do
transition :s_initial => :s_provisioning
end
after_transition :s_initial => :s_provisioning do |goal, transition|
# Do useful stuff here
true
end

event :provision do
transition :s_provisioning => :s_completed
end

before_transition :s_provisioning => :s_completed do |goal, transition|
artifact_type = transition.args[0]
params = transition.args[1]
# Useful stuff here
true
end

after_transition :s_provisioning => :s_completed do |goal, transition|
artifact_type = transition.args[0]
params = transition.args[1]
# Useful stuff here
end
end

def inject_expiration()
event :chron do
expired_callback = lambda \
do |goal|
return false if goal.expires_at == :never
goal.expires_at.to_i < DateTime.now.to_i
end
active_callback = lambda \
do |goal|
return true if goal.expires_at == :never
goal.expires_at.to_i >= DateTime.now.to_i
end
transition all - :s_expired => :s_expired, :if => expired_callback
end

before_transition all - :s_expired => :s_expired do |goal, transition|
goal.undo
end
end

现在,当我在类中打开一个 state_machine 定义时,我可以进行简单的类似宏的调用来注入(inject)代码:

state_machine :machine_state, :initial => :s_initial do
inject_provisioning
inject_expiration
end

希望其他人觉得这很有用。

最佳答案

很难确切地说出你想做什么,但希望这段代码能有所帮助

class Artifact < ActiveRecord::Base
extend Provision

attr_accessible :some_value, :state

state_machine :state, :initial => :initial do
event :foo do
transition :initial => :bar
end

Artifact.provision(self, :param1, :param2, :param3)

event :fud do
transition :bar => :initial
end

end
end

注意 - 我们混合使用 extend 而不是 include - 将方法放在类级别而不是实例,传递 self (这是状态机)到方法

module Provision
def provision(state_machine, *args)

state_machine do
event :provision do
transition :initial => :provisioned
end

event :deprovision do
transition :provisioned => :deprovisioned
end

before_transition :provisioned => :deprovisioned do |item, transition|
# transition.args.length == 0
args.each do |arg|
puts arg
end
end
end

end
end

关于ruby-on-rails - 将代码注入(inject) ruby​​ 状态机?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12150448/

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