【问题标题】:Printing variables打印变量
【发布时间】:2012-08-16 10:16:46
【问题描述】:

我的问题可能很简单,但我在任何地方都找不到答案。

创建类时,例如:

class Book
  @author = "blabla"
  @title = "blabla"
  @number_of_pages"

我想创建一个方法来打印我的变量。在这里我尝试时遇到问题:

def Print
  puts @author, @title, @number_of_pages
end

我什么也得不到。

当我尝试时:

def Print
  puts "@author, @title, @number_of_pages"
end

我直截了当:“@author,@title,@number_of_pages”

如何让Print 方法打印出变量的值?

【问题讨论】:

    标签: ruby oop


    【解决方案1】:

    您应该将变量初始化移动到initialize

    class Book
      def initialize
        @author = "blabla"
        @title = "blabla"
        @number_of_pages = 42 # You had a typo here...
      end
    end
    

    按照您在问题中使用的方式,变量是类实例变量(如果您对此感到好奇,可以在 Google 上搜索,但在这里并不真正相关)。

    初始化为(普通)实例变量,如果您只是想转储状态,则Print() 的第一个版本可以工作——它将每个参数打印在自己的行上。

    要使Print() 的第二个版本正常工作,您需要将变量包装在#{} 中以对其进行插值:

    def print # It's better not to capitalize your method names
      puts "#{@author}, #{@title}, #{@number_of_pages}"
    end
    

    【讨论】:

      【解决方案2】:

      除了 Darshan 已经非常出色的回答之外,这里是你可以做到的最佳方式

      class Book
      
        attr_accessor :author, :title, :number_of_pages 
        #so that you can easily read and change the values afterward
      
        def initialize author, title, number_of_pages = nil 
          #so that you don't really need to provide the number of pages
          @author = author
          @title = title
          @number_of_pages = number_of_pages
        end
      
        def print
          puts "#{@author}, #{@title}, #{@number_of_pages}" 
        end 
      end 
      
      my_book = Book.new("blabla", "blabla", 42)
      my_book.title = "this is a better title"
      my_book.print
      
      #=>blabla, this is a better title, 42
      

      【讨论】:

      • 例如 vars 你也可以使用#@var 而不是#{@var}。全局变量也一样 (#$var)。
      【解决方案3】:

      我认为Darshan Computing 已经很好地解决了您的问题。但在这里,我想为您提供实现这一目标的替代方法。

      我假设您想打印出类中的所有实例变量。 instance_variables 方法可以返回一个包含所有instance_variables 符号的数组。然后你可以迭代它们做任何你想做的事情。请注意:instance_variable_get 非常方便,但不是最佳实践。

      class Book
        attr_reader :author, :title, :number_of_pages
      
        def initialize(author, title, number_of_pages)
          @author = author
          @title = title
          @number_of_pages = number_of_pages
        end
      
        def print_iv(&block)
          self.instance_variables.each do |iv|
            name = iv
            value = send(iv.to_s.gsub(/^@/, ''))
            # value = instance_variable_get(iv) # Not recommended, because instance_variable_get is really powerful, which doesn't actually need attr_reader
            block.call(name, value) if block_given?
          end
        end
      end
      
      rb = Book.new("Dave Thomas", "Programming Ruby - The Pragmatic Programmers' Guide", 864)
      
      # rb.instance_variables #=> [:@author, :@title, :@number_of_pages]
      rb.print_iv do |name, value|
        puts "#{name} = #{value}"
      end
      #=> @author = Dave Thomas
      #=> @title = Programming Ruby - The Pragmatic Programmers' Guide
      #=> @number_of_pages = 864
      
      # You can also try instance_eval to run block in object context (current class set to that object)
      # rb.instance_eval do
      #   puts author
      #   puts title
      #   puts number_of_pages
      # end
      

      【讨论】:

        猜你喜欢
        • 2016-09-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-17
        • 2014-11-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多