在方法之间共享数据

Share data between methods

我有这个模块,它包含在 class:

module MyModule

    def self.included base
        base.extend ClassMethods
    end

    module ClassMethods
        def my_module_method data
            include MyModule::InstanceMethods

            after_save :my_module_process

            attr_accessor :shared_data
            shared_data = data
            # instance_variable_set :@shared_data, data
        end
    end

    module InstanceMethods

        private

        def my_module_process
            raise self.shared_data.inspect
            # raise instance_variable_get(:@shared_data).inspect
        end

    end

end

我想在 my_module_process 中使用传递给 my_module_methoddata(参数)。我使用了 attr_accessor 以及实例变量,但是它们中的任何一个 return nil.

由于您使用的是 rails,您的模块可以通过将其设为 AS::Concern

来大大简化
module MyModule
  extend ActiveSupport::Concern

  included do
    # after_save :my_module_process # or whatever
    cattr_accessor :shared_data
  end

  module ClassMethods
    def my_module_method(data)
      self.shared_data = data
    end
  end

  def my_module_process
    "I got this shared data: #{self.class.shared_data}"
  end
end

这里的重点是:

  • cattr_accessor,类似于attr_accessor,但定义了class级方法
  • self.class.shared_data 从实例中访问 class 级别的数据。

用法:

class Foo
  include MyModule
end

f = Foo.new
f.my_module_process # => "I got this shared data: "
Foo.my_module_method({foo: 'bar'})
f.my_module_process # => "I got this shared data: {:foo=>\"bar\"}"

I've used attr_accessor as well as instance variables, but either of them return nil.

在 ruby 中,了解什么是 self 在任何特定时刻都非常重要。这就是定义您可用的方法和实例变量的内容。作为练习,我建议您找出为什么 user.name returns 在这里为零(以及如何修复它)。

class User
  @name = 'Joe'

  def name
    @name
  end
end

user = User.new
user.name # => nil