在 Ruby 中定义 [方括号] 方法是如何工作的?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10018900/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How does defining [square bracket] method in Ruby work?
提问by oFca
I am going through Programming Ruby - a pragmatic programmers guideand have stumbled on this piece of code:
我正在阅读Programming Ruby - 一个实用的程序员指南,并偶然发现了这段代码:
class SongList
def [](key)
if key.kind_of?(Integer)
return @songs[key]
else
for i in [email protected]
return @songs[i] if key == @songs[i].name
end
end
return nil
end
end
I do not understand how defining [ ] method works?
我不明白定义 [] 方法是如何工作的?
Why is the key outside the [ ], but when the method is called, it is inside [ ]?
为什么key在[]外面,调用方法的时候却在[]里面?
Can key be without parenthesis?
键可以不带括号吗?
I realize there are far better ways to write this, and know how to write my own method that works, but this [ ] method just baffles me... Any help is greatly appreciated, thanks
我意识到有更好的方法来写这个,并且知道如何编写我自己的有效方法,但是这个 [ ] 方法只是让我感到困惑......非常感谢任何帮助,谢谢
采纳答案by Gazler
Methods in ruby, unlike many languages can contain some special characters. One of which is the array lookup syntax.
ruby 中的方法,不像许多语言可以包含一些特殊字符。其中之一是数组查找语法。
If you were to implement your own hash class where when retrieving an item in your hash, you wanted to reverse it, you could do the following:
如果您要实现自己的散列类,在其中检索散列中的项目时,您想反转它,您可以执行以下操作:
class SillyHash < Hash
def [](key)
super.reverse
end
end
You can prove this by calling a hash with the following:
您可以通过使用以下内容调用哈希来证明这一点:
a = {:foo => "bar"}
=> {:foo=>"bar"}
a.[](:foo)
=> "bar"
a.send(:[], :foo)
=> "bar"
So the def [] defined the method that is used when you do my_array["key"]Other methods that may look strange to you are:
所以 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
Just to clarify, the definition of a []method is unrelated to arrays or hashes. Take the following (contrived) example:
澄清一下,[]方法的定义与数组或散列无关。以以下(人为的)示例为例:
class B
def []
"foo"
end
end
B.new[]
=> "foo"
回答by J?rg W Mittag
It's just syntactic sugar. There are certain syntax patterns that get translated into message sends. In particular
这只是语法糖。有某些语法模式可以转换为消息发送。特别是
a + b
is the same as
是相同的
a.+(b)
and the same applies to ==, !=, <, >, <=, >=, <=>, ===, &, |, *, /, -, %, **, >>, <<, !==, =~and !~as well.
这同样适用于==,!=,<,>,<=,>=,<=>,===,&,|,*,/,-,%,**,>>,<<,!==,=~和!~也。
Also,
还,
!a
is the same as
是相同的
a.!
and the same applies to ~.
这同样适用于~.
Then,
然后,
+a
is the same as
是相同的
a.+@
and the same applies to -.
这同样适用于-.
Plus,
加,
a.(b)
is the same as
是相同的
a.call(b)
There is also special syntax for setters:
setter 也有特殊的语法:
a.foo = b
is the same as
是相同的
a.foo=(b)
And last but not least, there is special syntax for indexing:
最后但并非最不重要的是,索引有特殊的语法:
a[b]
is the same as
是相同的
a.[](b)
and
和
a[b] = c
is the same as
是相同的
a.[]=(b, c)
回答by jigfox
the square brackets are the method name like Array#sizeyou have Array#[]as a method and you can even use it like any other method:
方括号是方法名称,就像Array#size您Array#[]作为方法一样,您甚至可以像任何其他方法一样使用它:
array = [ 'a', 'b', 'c']
array.[](0) #=> 'a'
array.[] 1 #=> 'b'
array[2] #=> 'c'
the last one is something like syntactic sugar and does exactly the same as the first one. The Array#+work similar:
最后一个类似于语法糖,与第一个完全相同。在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' ]
You can even add numbers like this:
您甚至可以添加这样的数字:
1.+(1) #=> 2
1.+ 1 #=> 2
1 + 1 #=> 2
the same works with /, *, -and many more.
同样适用于/, *,-等等。
回答by codeSeeker
It's an operator overloader, it overrides or supplements the behavior of a method inside a class you have defined, or a class the behavior of which you are modifying. You can do it to other operators different from []. In this case you are modifying the behavior of [] when it is called on any instances of class SongList.
它是一个运算符重载器,它覆盖或补充您已定义的类或您正在修改其行为的类中方法的行为。您可以对不同于 [] 的其他运算符执行此操作。在这种情况下,您正在修改在类 SongList 的任何实例上调用 [] 时的行为。
If you have songlist = SongList.new and then you do songlist["foobar"] then your custom def will come into operation and will assume that "foobar" is to be passed as the parameter (key) and it will do to "foobar" whatever the method says should be done to key.
如果你有 songlist = SongList.new 然后你做 songlist["foobar"] 那么你的自定义 def 将开始运行,并假设“foobar”将作为参数(键)传递,它将对“foobar”执行“无论方法说什么,都应该对密钥进行操作。
Try
尝试
class Overruler
def [] (input)
if input.instance_of?(String)
puts "string"
else
puts "not string"
end
end
end
foo = Overruler.new
foo["bar"].inspect
foo[1].inspect

![ruby Bundler 不使用 rbenv,找不到 [gem]](/res/img/loading.gif)