如何在ruby中从外部访问类变量?

时间:2016-12-07 20:44:46

标签: ruby class-variables

我正在尝试从类外部的方法访问类变量。

这是我的班级:

class Book

  @@bookCount = 0
  @@allBooks = []

  def self.allBooks
    @@allBooks
  end

  def self.bookCount
    @@bookCount
  end

  attr_accessor :name,:author,:date,:genre,:rating

  def initialize(name, author, date, genre, rating)
      @name = name
      @author = author
      @date = date
      @genre = genre
      @rating = rating
      @@bookCount += 1
      @@allBooks << self
  end

end

这是尝试访问类变量@@ bookCount

的方法
def seeBookShelf
  if @@bookCount == 0
    puts "Your bookshelf is empty."
  else
    puts "You have " + @bookCount + " books in your bookshelf:"
    puts allBooks
  end
end

当我尝试执行该方法时,我得到了这个:

undefined local variable or method `bookCount' for main:Object (NameError)

如何从外部访问bookCount?

5 个答案:

答案 0 :(得分:6)

使用class_variable_get访问类外的类变量:

class Foo
  @@a = 1
end

Foo.class_variable_get(:@@a)
=> 1

答案 1 :(得分:3)

对于大多数情况,类实例变量优先于类变量。当与继承一起使用时,后者容易出现各种奇怪的行为。

考虑:

class Book
  @book_count = 0
  @all_books = []

  class << self
    attr_reader :book_count
    attr_reader :all_books
  end

  # further code omitted.

end

使用此代码Book.book_count和Book.all_books获取预期数据。

答案 2 :(得分:0)

您必须指定变量的类:

def seeBookShelf
  if Book.bookCount == 0
    puts "Your bookshelf is empty."
  else
    puts "You have " + Book.bookCount + " books in your bookshelf:"
    puts Book.allBooks
  end
end

答案 3 :(得分:0)

您需要一个getter来访问类变量,请尝试此代码。 有关说明,请参阅http://www.railstips.org/blog/archives/2006/11/18/class-and-instance-variables-in-ruby/。 你也最好使用字符串插值,否则你会得到一个Type错误,也就是更多的Rubyesque。

class Book
  @@bookCount = 0

  def self.bookCount
    @@bookCount
  end
end

def seeBookShelf
  if Book.bookCount == 0
    puts "Your bookshelf is empty."
  else
    puts "You have #{Book.bookCount} books in your bookshelf:"
  end
end

seeBookShelf # Your bookshelf is empty.

答案 4 :(得分:0)

您可以使用class_eval来评估特定类范围内的代码块:

class Book
  @@bookCount = 1
end

Book.class_eval '@@bookCount'
# => 1

只是为了好玩......你实际上可以用class_eval

做各种各样的诡计
Book.class_eval { @@bookCount = 5 }
Book.class_eval '@@bookCount'
# => 5

Book.class_eval do
  def self.hey_look_a_new_method
    return "wow"
  end
end

Book.hey_look_a_new_method
# => "wow"