如何在Ruby中定义[方括号]方法?

oFc*_*Fca 42 ruby methods

我正在编写Ruby编程 - 一个实用的程序员指南,并且偶然发现了这段代码:

class SongList
  def [](key)
    if key.kind_of?(Integer)
      return @songs[key]
    else
      for i in 0...@songs.length
        return @songs[i] if key == @songs[i].name
      end
    end
    return nil
  end
end
Run Code Online (Sandbox Code Playgroud)

我不明白定义[]方法是如何工作的?

为什么键在[]之外,但是当调用方法时,它在[]里面?

键可以没有括号吗?

我知道有更好的方法来写这个,并知道如何编写我自己的方法,但这个[]方法只是让我感到困惑...任何帮助非常感谢,谢谢

Jör*_*tag 46

这只是语法糖.某些语法模式可以转换为消息发送.特别是

a + b
Run Code Online (Sandbox Code Playgroud)

是相同的

a.+(b)
Run Code Online (Sandbox Code Playgroud)

这同样适用于==,!=,<,>,<=,>=,<=>,===,&,|,*,/,-,%,**,>>,<<,!==,=~!~也.

也,

!a
Run Code Online (Sandbox Code Playgroud)

是相同的

a.!
Run Code Online (Sandbox Code Playgroud)

这同样适用于~.

然后,

+a
Run Code Online (Sandbox Code Playgroud)

是相同的

a.+@
Run Code Online (Sandbox Code Playgroud)

这同样适用于-.

加,

a.(b)
Run Code Online (Sandbox Code Playgroud)

是相同的

a.call(b)
Run Code Online (Sandbox Code Playgroud)

setter还有特殊的语法:

a.foo = b
Run Code Online (Sandbox Code Playgroud)

是相同的

a.foo=(b)
Run Code Online (Sandbox Code Playgroud)

最后但并非最不重要的是,索引有特殊的语法:

a[b]
Run Code Online (Sandbox Code Playgroud)

是相同的

a.[](b)
Run Code Online (Sandbox Code Playgroud)

a[b] = c
Run Code Online (Sandbox Code Playgroud)

是相同的

a.[]=(b, c)
Run Code Online (Sandbox Code Playgroud)

  • @SooDesuNe:它*确实*但是调用`to_s`。 (2认同)

Gaz*_*ler 37

与许多语言不同,ruby中的方法可以包含一些特殊字符.其中之一是数组查找语法.

如果您要实现自己的哈希类,在哈希中检索项目时,您想要反转它,您可以执行以下操作:

class SillyHash < Hash

  def [](key)
    super.reverse
  end

end
Run Code Online (Sandbox Code Playgroud)

您可以通过使用以下内容调用哈希来证明这一点:

a = {:foo => "bar"}
 => {:foo=>"bar"} 
a.[](:foo)
 => "bar" 
a.send(:[], :foo)
 => "bar" 
Run Code Online (Sandbox Code Playgroud)

所以def []定义了你做的时候使用的方法.my_array["key"] 其他可能看起来很奇怪的方法是:

class SillyHash < Hash

  def [](key)
    super.reverse
  end

  def []=(key, value)
    #do something
  end

  def some_value=(value)
    #do something
  end

  def is_valid?(value)
    #some boolean expression
  end

end
Run Code Online (Sandbox Code Playgroud)

只是为了澄清,[]方法的定义与数组或散列无关.采取以下(人为的)示例:

class B
  def []
    "foo"
  end
end

 B.new[]
 => "foo" 
Run Code Online (Sandbox Code Playgroud)

  • @Gazler修复你的代码.方法内的超级[key]将无法正常工作.超级(关键).反向会.超级[关键] =等等不会起作用.超级(关键,价值)会.你应该刷新自己如何在ruby方法中使用super! (3认同)

jig*_*fox 8

方括号是方法名称,就像Array#size你拥有Array#[]的方法一样,你甚至可以像任何其他方法一样使用它:

array = [ 'a', 'b', 'c']
array.[](0) #=> 'a'
array.[] 1  #=> 'b'
array[2]    #=> 'c'
Run Code Online (Sandbox Code Playgroud)

最后一个是类似于语法糖的东西,与第一个完全相同.在Array#+类似的工作:

array1 = [ 'a', 'b' ]
array2 = [ 'c', 'd' ]
array1.+(array2) #=> [ 'a', 'b', 'c', 'd' ]
array1.+ array2  #=> [ 'a', 'b', 'c', 'd' ]
array1 + array2  #=> [ 'a', 'b', 'c', 'd' ]
Run Code Online (Sandbox Code Playgroud)

你甚至可以添加这样的数字:

1.+(1) #=> 2
1.+ 1  #=> 2
1 + 1  #=> 2
Run Code Online (Sandbox Code Playgroud)

同样的作品有/,*,-等等.