ruby类变量中访问器方法的简写

时间:2015-10-24 05:52:29

标签: ruby

我想要一些简短的方法,而不是为类变量创建访问器方法的重复方法。在这里,我看到有太多相同的代码,即方法。我们的实例变量是否有任何简短的方法。 @foobar attr_accessor :foobar

class User
    @@user_id = 0
    @@user_long = 0
    @@user_lat = 0 

    # User ID

    def self.user_id=(id)
        @@user_id = id
    end

    def self.user_id
        @@user_id
    end

    # Longitude 

    def self.user_long=(longitude)
        @@user_long = longitude
    end

    def self.user_long
        @@user_long
    end

    # Latitude 

    def self.user_lat=(latitude)
        @@user_lat = latitude
    end

    def self.user_lat
        @@user_lat
    end
end


User.user_id = 23423423
User.user_long = -342.34
User.user_lat = 343.3

puts User.user_lat
puts User.user_lat
puts User.user_id

3 个答案:

答案 0 :(得分:4)

你可以这样做:

class User
  @user_id = 0
  @user_long = 0
  @user_lat = 0 
  class << self
    attr_accessor :user_id, :user_long, :user_lat
  end
end

答案 1 :(得分:2)

一般来说,最好使用实例变量而不是类变量,因为类变量的共享语义有些奇怪:

class User
  class << self
    attr_accessor :user_id, :user_long, :user_lat
  end

  self.user_id   = 0
  self.user_long = 0
  self.user_lat  = 0 
end

User.user_id   #=> 0
User.user_long #=> 0
User.user_lat  #=> 0

User.user_id   = 23423423
User.user_long = -342.34
User.user_lat  = 343.3

User.user_id   #=> 23423423
User.user_long #=> -342.34
User.user_lat  #=> 343.3

但是如果你绝对必须使用类变量,你可以简单地编写自己的方法来生成setter和getter。它不像Module#attr_accessor那样神奇,它就像任何其他方法一样:

class Module
  def cvar_reader(*names)
    names.each do |name|
      define_singleton_method(name) { class_variable_get(:"@@#{name}") }
    end
  end

  def cvar_writer(*names)
    names.each do |name|
      define_singleton_method(:"#{name}=") {|value| class_variable_set(:"@@#{name}", value) }
    end
  end

  def cvar_accessor(*names)
    cvar_reader *names
    cvar_writer *names
  end
end

class User
  cvar_accessor :user_id, :user_long, :user_lat

  self.user_id   = 0
  self.user_long = 0
  self.user_lat  = 0 
end

User.user_id   #=> 0
User.user_long #=> 0
User.user_lat  #=> 0

User.user_id   = 23423423
User.user_long = -342.34
User.user_lat  = 343.3

User.user_id   #=> 23423423
User.user_long #=> -342.34
User.user_lat  #=> 343.3

然而,无论您使用类实例变量还是类变量,它似乎都是一种奇怪的设计。当你的系统中不能有多个用户时,为什么要上课呢?为什么不只使用一个对象?

class << (User = Object.new)
  attr_accessor :user_id, :user_long, :user_lat
end

User.user_id   = 0
User.user_long = 0
User.user_lat  = 0 

User.user_id   #=> 0
User.user_long #=> 0
User.user_lat  #=> 0

User.user_id   = 23423423
User.user_long = -342.34
User.user_lat  = 343.3

User.user_id   #=> 23423423
User.user_long #=> -342.34
User.user_lat  #=> 343.3

答案 2 :(得分:1)

你可能正在寻找的东西是这样的,

class User
  class << self
    attr_accessor :user_id
  end
end

这将在类的metaclass上创建实例变量,而不是类变量。这可能会为您提供所需,但我建议您阅读并理解Ruby的对象模型。