Ruby实例变量和局部变量

时间:2016-12-31 13:33:09

标签: ruby-on-rails ruby

我一直认为实例变量只在类的定义中使用,可以在类中访问。当我学习rails时,我正在看一个这样的例子:

class Movie
  def initialize(isbn)
    @isbn = isbn
  end
  def isbn
    @isbn
  end
end
@movie = Movie.new("0702")
@movie.isbn

我很困惑,实例变量出现在类定义之外。为什么要使用@movie而不是局部变量“movie”?

跟进问题:

  1. 由于实例变量可以存在于另一个范围内,当程序需要创建多个新对象时,它们是否都具有相同的名称@movie?新对象是否总是超过旧对象?

  2. 在较大的程序(如MVC应用程序)中,@ movie是否共享所有文件(模型,视图,控制器)?

3 个答案:

答案 0 :(得分:2)

  

我一直认为实例变量只在类的定义中使用,可以在类中访问。

那是错的。实例变量与类完全无关。实例变量属于对象(又名实例),这就是它们被称为实例变量的原因。

  

我很困惑,实例变量出现在类定义之外。

实例变量出现在类定义之外是完全正确的。毕竟,示例中的其他实例变量也不在类定义中,它们在方法定义中。

  

为什么要使用@movie而不是局部变量“movie”?

在您发布的代码段中没有理由这样做。但如果它是一个更大的计划的一部分,那么肯定有充分的理由这样做。

答案 1 :(得分:0)

实例变量的另一个范围不是局部变量。 在类之外,您仍然在主Object类中,您可以在以下示例中生成的错误中看到。 所以在我的例子中,如果我必须在类似测试的方法中使用movie变量,我需要一个实例变量或(更好)我需要将它作为参数传递。

在这种情况下,它们在控制命名空间方面并不比全局变量好多少。虽然我过去读过它们但找不到关于Ruby的好文章并使用变量和命名空间。如果我这样做,我会将其添加到答案中。

class Movie
  def initialize(isbn)
    @isbn = isbn
  end
  def isbn
    @isbn
  end
end
@movie = Movie.new("0702")
@movie.isbn
movie = "you won't see me"

def test
  p @movie # #<Movie:0x00000002d1e7f8 @isbn="0702">
  p movie # error undefined local variable or method `movie' for main:Object
end

test

答案 2 :(得分:-3)

您正在混淆类实例和实例变量。类实例(有时也称为Object)是示例中的public static async Task<string> decrypt(string encrypted, string privateKey) { // read private certificate into RSACryptoServiceProvider from file RSACryptoServiceProvider rsa = DecodePrivateKeyInfo( DecodePkcs8PrivateKey( File.ReadAllText( privateKey ) ) ); // decode base64 to bytes byte[] encryptedBytes = Convert.FromBase64String( encrypted ); int bufferSize = (int)(rsa.KeySize / 8); // initialize byte buffer based on certificate block size byte[] buffer = new byte[bufferSize]; // the number of bytes to decrypt at a time int bytesReadTotal = 0; int bytesRead = 0; string decrypted = ""; byte[] decryptedBytes; // convert byte array to stream using ( Stream stream = new MemoryStream( encryptedBytes ) ) { // loop through stream for each block of 'bufferSize' while ( ( bytesRead = await stream.ReadAsync( buffer, bytesReadTotal, bufferSize ) ) > 0 ) { // decrypt this chunk decryptedBytes = rsa.Decrypt( buffer, false ); // account for bytes read & decrypted bytesReadTotal = bytesReadTotal + bytesRead; // append decrypted data as string for return decrypted = decrypted + Encoding.UTF8.GetString( decryptedBytes ); } } return decrypted; }

换句话说,当你在那里做Class.new(@movie)时,你通过创建一个新的电影实例来初始化/实例化一个类。

另一方面,

Movie.new是一个实例变量(有时也称为成员变量),因为它在类isbn中定义,并且可供该类的每个实例访问。它被称为实例变量的原因是因为类电影的每个实例 - 比如你有另一个名为Movie的实例,它将拥有自己的@movie2 = Movie.new("1234")副本,其值为1234

实例变量是在类中定义的变量(即成员变量),对于该变量,类的每个实例化对象都有一个单独的副本或实例