在Ruby模块中动态创建访问器

在Ruby模块中动态创建访问器

本文介绍了在Ruby模块中动态创建访问器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

限时删除!!

我在Ruby中有一个Config模块,我希望能够向其中添加任意变量.我使用method_missing和instance_variable_set创建了它,如下所示:

I have a Config module in Ruby that I want to be able to add arbitrary variables to. I have created it using method_missing and instance_variable_set as follows:

module Conf
  #add arbitrary methods to config array
  def self.method_missing(m, *args)
    args = args.pop if args.length==1
    instance_variable_set("@#{m}", args)
  end
end

但是,我在动态创建访问器时遇到了麻烦.当我尝试如下使用attr_accessor时:

However, I'm having trouble with dynamically creating accessors. When I try to use attr_accessor as follows:

module Conf
  #add arbitrary methods to config array
  def self.method_missing(m, *args)
    args = args.pop if args.length==1
    instance_variable_set("@#{m}", args)
    module_eval("attr_accessor :#{m}")
  end
end

我得到以下信息:

Conf :: s3_key('1234ABC')#Conf :: s3_key = nil

Conf::s3_key('1234ABC') #Conf::s3_key=nil

如果我尝试单独创建访问器,则:

And if I try to create the accessors separately:

module Conf
  #add arbitrary methods to config array
  def self.method_missing(m, *args)
    args = args.pop if args.length==1
    instance_variable_set("@#{m}", args)
    module_eval("def self.#{m};@#{m};end")
    module_eval("def self.#{m}=(val);@#{m}=val;end")
  end
end

发生以下情况:

Conf::s3_key('1234ABC') # Conf::s3_key='1234ABC' - correct

但是如果我尝试覆盖该值,则会收到错误消息

but if I try to overwrite the value I get an error

Conf::s3_key('1234ABC') # ok
Conf::s3_key('4567DEF') #(eval):1:in `s3_key': wrong number of arguments (1 for 0) (ArgumentError)

我在做什么错了?

推荐答案

首先,即使正常描述,attr_accessor也不能用于Module.

First, attr_accessor is unusable for Module, even if normally described.

module Conf
  attr_accessor :s3_key
end

第二,覆盖错误是因为method_missing仅执行一次

Second, the error of overwriting is because method_missing is executed only once

  def self.method_missing(m, *args)
    #:
    instance_variable_set("@#{m}", args)
    module_eval("def self.#{m};@#{m};end") # <- method defined

该方法在第一次调用中定义.并且参数的数量为0

the method is defined in first call.And the number of arguments is 0

Conf::s3_key('1234ABC') # call method_missing
Conf::s3_key('4567DEF') # call self.s3_key()

例如,像这样:

module Conf
  def self.method_missing(m, *args)
    args = args.pop if args.length==1
    instance_variable_set("@#{m}", args)
    module_eval(<<EOS)
def self.#{m}(*args)
  if (args.empty?)
    @#{m}
  else
    @#{m} = (args.length==1) ? args.pop : args
  end
end
EOS
  end
end

Conf::s3_key('foo')
Conf::s3_key('bar')
p Conf::s3_key                   # "bar"

module Conf
  def self.method_missing(m, *args)
    if (m.to_s =~ /^(.+)=$/)
      args = args.pop if args.length==1
      instance_variable_set("@#{$1}", args)
    else
      instance_variable_get("@#{m}")
    end
  end
end

Conf::s3_key = 'foo'
Conf::s3_key = 'bar'
p Conf::s3_key                   # "bar"

这篇关于在Ruby模块中动态创建访问器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

1403页,肝出来的..

09-07 03:07