在类方法中使用实例变量-Ruby [英] Using Instance Variables in Class Methods - Ruby

查看:107
本文介绍了在类方法中使用实例变量-Ruby的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类似下面的类,并且我使用实例变量(数组)来避免使用很多方法参数.

I have a class something like below, and I used instance variables (array) to avoid using lots of method parameters.

它能按我的预期工作,但这是一个好习惯吗? 实际上,我不希望这样能起作用,但是我想类方法不能像其他语言中的静态方法一样起作用.

It works as I expected but is that a good practice? Actually I wouldn't expect that worked, but I guess class methods are not working as static methods in other languages.

class DummyClass
  def self.dummy_method1
    @arr = []
    # Play with that array
  end

  def self.dummy_method2
    # use @arr for something else
  end
end

推荐答案

实例变量在Ruby中的类上起作用的原因是Ruby类实例本身(类

The reason instance variables work on classes in Ruby is that Ruby classes are instances themselves (instances of class Class). Try it for yourself by inspecting DummyClass.class. There are no "static methods" in the C# sense in Ruby because every method is defined on (or inherited into) some instance and invoked on some instance. Accordingly, they can access whatever instance variables happen to be available on the callee.

由于DummyClass是一个实例,因此可以拥有自己的实例变量.您甚至可以访问那些实例变量,只要您有对类的引用即可(因为类名是常量,所以应该始终如此).在任何时候,您都可以调用::DummyClass.instance_variable_get(:@arr)并获取该实例变量的当前值.

Since DummyClass is an instance, it can have its own instance variables just fine. You can even access those instance variables so long as you have a reference to the class (which should be always because class names are constants). At any point, you would be able to call ::DummyClass.instance_variable_get(:@arr) and get the current value of that instance variable.

关于这是否是一件好事,取决于方法.

As for whether it's a good thing to do, it depends on the methods.

如果@arr在逻辑上是实例/类DummyClass的状态",则将其存储在实例变量中.如果@arr仅在dummy_method2中用作操作快捷方式,则将其作为参数传递.举一个使用实例变量方法的例子,考虑一下Rails中的ActiveRecord.它允许您执行以下操作:

If @arr is logically the "state" of the instance/class DummyClass, then store it in instance variable. If @arr is only being used in dummy_method2 as an operational shortcut, then pass it as an argument. To give an example where the instance variable approach is used, consider ActiveRecord in Rails. It allows you to do this:

u = User.new
u.name = "foobar"
u.save

在这里,已分配给用户的名称是合法存在于该用户上的数据.如果在#save调用之前询问此时用户名是什么",您将回答"foobar".如果您深入研究内部结构(您将深入研究很多元编程,那么您会发现它们恰恰为此使用了实例变量).

Here, the name that has been assigned to the user is data that is legitimately on the user. If, before the #save call, one were to ask "what is the name of the user at this point", you would answer "foobar". If you dig far enough into the internals (you'll dig very far and into a lot of metaprogramming, you'll find that they use instance variables for exactly this).

我使用的示例包含两个单独的公共调用.要查看仅进行一次调用但仍使用实例变量的情况,请查看

The example I've used contains two separate public invocations. To see a case where instance variables are still used despite only one call being made, look at the ActiveRecord implementation of #update_attributes. The method body is simply load(attributes, false) && save. Why does #save not get passed any arguments (like the new name) even though it is going to be in the body of save where something like UPDATE users SET name='foobar' WHERE id=1;? It's because stuff like the name is information that belongs on the instance.

相反,我们可以看一个实例变量无用的情况.查看 #link_to_if 的实现接受布尔型参数(通常是源代码中的表达式)以及#link_to通常接受的参数(例如链接到的URL)的方法.当布尔条件为真时,它需要将其余参数传递给#link_to并调用它.在这里分配实例变量没有多大意义,因为您不会说这里的调用上下文(渲染器)在实例中包含该信息.渲染器本身没有要链接的URL",因此,不应将其隐藏在实例变量中.

Conversely, we can look at a case where instance variables would make no sense to use. Look at the implementation of #link_to_if, a method that accepts a boolean-ish argument (usually an expression in the source code) alongside arguments that are ordinarily accepted by #link_to such as the URL to link to. When the boolean condition is truthy, it needs to pass the rest of the arguments to #link_to and invoke it. It wouldn't make much sense to assign instance variables here because you would not say that the invoking context here (the renderer) contains that information in the instance. The renderer itself does not have a "URL to link to", and consequently, it should not be buried in an instance variable.

这篇关于在类方法中使用实例变量-Ruby的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆