简体   繁体   中英

What are all the different uses of the [square brackets] in Ruby?

I'm coming across the square bracket [] syntax quite a bit in Ruby, but it never seems to be doing the same thing. Can anyone list all the different uses for the square brackets [] in Ruby so my mind can get a handle on this seemingly endlessly versatile little symbol? (How is it possible that one symbol can do so much without the Ruby interpreter getting confused?)

Examples:

  • [] and []= methods
  • %q[...]
  • [1,2,3][0]
  • hash["a"] = 3
  • ary = []
  • /[^A-Fa-f0-9]/
  • "Is a string"[5,3]

The square brackets are in two strict contexts and one optional one:

Defining Arrays
Arrays, ie a data structure providing and ordered list of elements can be specified in code by using a syntax like [1,2,3] . This creates an array with the three elements 1 , 2 , and 3 in exactly that order. you can then iterate over the array using on of the iterator functions like each or map or you can directly access a specific elements by its index id as shown below.

Accessing Elements in Arrays and Hashes
Hashes (also called hashmaps, dictionaries, or associative arrays in other languages) also contain elements similar to arrays. The are different from this in the way that they store their data unordered . Data is not accessed by an integer id as is the case by arrays but with an arbitrary key (commonly a symbol or a string). This is different from eg PHP where the same Array type is used for both.

This access to the data is facilitated by methods called [] and []= for both hashes and arrays.

my_array = [:a, :b, :c]
second_element = my_array[1]
# => :b
# notice that the first element in arrays always has the index 0

my_hash = {:a => 1, :b => 2, :c => 3}
element_of_b = my_hash[:b]
# => 2

This is the common use case for the brackets. In Ruby code, you might sometimes see other classes implementing the bracket functions. They do so to allow an access similar to either arrays or hashes and it is then generally expected that these classes behave similar to those but this is in no way enforced. See also Duck Typing .

% Notation
Ruby has a third syntax to create strings (and other objects) apart from the common. Using this syntax, the literal string in code are not enclosed by " or ' but use a special delimiter. It starts with a percent sign, a single character specifying the object to be created and almost any character to chose as a delimiter:

a = %w[foo bar baz]
b = %w{foo bar baz}
c = %wxfoo bar bazx
d = ["foo", "bar", "baz"]

All three example create the same array. Please see the some documentation on how to use this syntax and which other modifier characters are available in Ruby.

While it is common to use brackets here, it is on no way required and can be substituted if required. It is just advisory here as the most common usage of this notation is to create an array of elements from a whitespace-seperated string (as seen above). As such, the usage of brackets makes it further clear that an array is returned as the syntax looks similar to the basic array specification.

Okay, just for my own notes I have gone and had a closer look at this and, building on Holger Just's answer , come up with the following: the use of square brackets in Ruby can be divided into 6 uses, 3 of them a part of Ruby's method definitions and 3 of them semantic constructs.

Method definition

Object creation via class methods Array::[], Hash::[]

Array.[](1,2,3) #=> [1,2,3]                        #Un-sugared notation
Array["a","b","c"] #=> ["a","b","c"]               #Sugared equivalent
Hash["a", 100, "b", 200] #=> {"a"=>100, "b"=>200}  

Nothing to do with literal constructors, although it does the same thing.

Element reference via instance methods Array#[], Bignum#[], Continuation#[], Fixnum#[], Hash#[], MatchData#[], Method#[], Proc#[], String#[], Struct#[], Symbol#[], Thread#[], and class methods Dir::[], ENV::[]

ary = [1,2,"abc", [15,16,[26,27]]]  
ary.[](2) #=> "abc"                #Un-sugared notation
ary[2] #=> "abc"                   #Sugared equivalent
ary[0,2] #=> [1,2]  
ary[3][2][1] #=> 26  
[1,2,3][0] #=> 1  
"Is a string"[7,3] #=> "rin"  

Element assignment via instance methods Array#[]=, Hash#[]=, String#[]=, Struct#[]=, Thread#[]=, and class method ENV::[]=

ary = [1,2,3]  
ary.[]=(1,"abc") #=> [1,"abc",3]    #un-sugared notation
ary[2] = "def" #=> [1,"abc","def"]  #Sugared equivalent
hash = {"a"=>1, "b"=>2}  
hash["a"] = 3 #=> {"a"=>3, "b"=>2}  

Semantic constructs

Object creation via the array literal constructor

ary = []  

There are a bunch of literal constructors in Ruby that create an object of the relevant class via the use of (usually) a simple symbol pair, square brackets being the literal constructor for array objects: Array [] , Hash {} , Proc ->(){} , Range .. and ... , Regexp // , String "" and '' , Symbol : and :"" .

Object creation via the % notation

%q[hello there you] #=> "hello there you"           # String % notation  
%w[hello there you] #=> ["hello", "there", "you"]   # Array % notation  

It is not, strictly speaking, square-bracket notation, but rather two-symbol-pair notation of which you can use square brackets if you wish. So %q@hello there you@ is equally valid.

Ruby's regular expressions

/[^A-Fa-f0-9]/  

Square brackets indicate character classes in Ruby regular expressions.

I did find another use of the [] , as a pattern for use in the Dir::glob method, but its supposed to act exactly as it does in regular expressions. Still, it indicates that there are possibly more uses hidden away in Ruby's 1500+ methods.

handy syntax for instantiating structs with square brackets

irb(main):001:0> Point = Struct.new(:x, :y)                         
=> Point                      
irb(main):002:0> point = Point[1,2]                                 
=> #<struct Point x=1, y=2>   
irb(main):003:0> point.x                   
=> 1                           
irb(main):004:0> point.y                    
=> 2     

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM