【问题标题】:What are the downsides to declaring "instance" variables at the class scope in Ruby?在 Ruby 的类范围内声明“实例”变量有什么缺点?
【发布时间】:2013-01-20 20:19:58
【问题描述】:

我几乎从未在 Ruby 代码中看到过这种情况,但它似乎是有效的:

class Foo
  @bar = "bar"

  def self.print_bar
    puts @bar
  end
end

我对上面的解释是@barFoo 的实例变量,它是Class 的单例(?)实例。

这似乎不同于 类变量(例如,@@baz),它们可以在类范围和实例范围内访问。

像上面的 sn-p 这样的代码有什么缺点(如果有的话)?还是完全合理的代码?

【问题讨论】:

    标签: ruby scope instance-variables


    【解决方案1】:

    一个潜在的缺点是@bar 不适用于Foo 的子类。

    class Parent
      @bar = 3
      def self.print_bar
        puts @bar # nil
      end
    end
    
    class Child < Parent
    
    end
    
    Parent.print_bar # 3
    Child.print_bar # nil
    

    【讨论】:

      【解决方案2】:

      未初始化的实例变量将具有nil 值,而未初始化的类变量将抛出错误。正如其他人所补充的,类变量可用于子类。

      这是一个链接,讨论了我认为有帮助的两个:

      http://www.railstips.org/blog/archives/2006/11/18/class-and-instance-variables-in-ruby/

      【讨论】:

      • 这不是倒退吗?根据我的测试,如果没有变量被初始化,puts @bar 输出 nil 而puts @@bar 引发错误:“NameError: uninitialized class variable @@bar in Foo.”
      • 是的,对不起。我修好了。
      【解决方案3】:

      是的,这是完全有效的。它也被广泛使用,通常推荐用于具有非常大范围的类变量(类、类的所有实例、所有子类、所有子类的所有实例……)。

      没有缺点。类是对象。对象可以有实例变量。没什么。 Ruby 的对象模型真的比人们(甚至 Ruby 教程的作者)想要相信的要简单得多。

      【讨论】:

      • 谢谢!我认为“非常广泛使用”必须取决于您从事的项目 - 我问的全部原因是我以前从未见过这个。但这很好知道。
      【解决方案4】:

      代码有效。您正在使用类实例变量。正如 Jörg 所说,它们通常比类变量更受欢迎。它们都可以实现相同的目的,但类变量有一些陷阱。请参阅Class and Instance Variables In Ruby,了解有关类变量与类实例变量的优缺点的良好讨论。

      使用类实例变量的一个缺点是它们看起来与“普通”实例变量相同。这会让新的 Ruby 程序员措手不及。下面的self.print_barprint_bar 方法指向不同的@bar 实例变量。

      class Foo
        @bar = "bar"
      
        def initialize
          @bar = "foo"
        end
      
        def self.print_bar
          puts @bar #=> "bar"
        end
      
        def print_bar
          puts @bar #=> "foo"
        end
      end
      

      在我看来这不是一个很大的缺点,但你问了:)

      类实例变量对子类不可用这一事实不一定是不利的。这完全取决于您希望程序的行为方式。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-03-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多