String#[] (brackets)
This week we're throwing a String appreciation party! 🎉
First up, let's explore the versatile String#[] method, which allows us to access substrings in various ways.
string = "Hello, Ruby!"
# We can access characters with a single index
string[0] # => "H"
# Negative indices count from the end
string[-1] # => "!"
# We can access substrings with a start index and length
string[7, 4] # => "Ruby"
# Or with a range
string[7..10] # => "Ruby"
# Ranges from positive to negative indices are fine too
string[7..-2] # => "Ruby"
# We can also pass a String
string["Ruby"] # => "Ruby"
# If the substring is not found, it returns nil
string["Python"] # => nil
# We can use regex to extract patterns
string[/R\w+/] # => "Ruby"
# If no match is found, it returns nil
string[/P\w+/] # => nil
const string = "Hello, Ruby!";
// JavaScript can bracket access single characters too
string[0]; // => "H"
// But negative indices must be manually calculated
string[string.length - 1]; // => "!"
// We can get a substring with index and length via substr
string.substr(7, 4); // => "Ruby"
// Or with start and end indices via substring
string.substring(7, 11); // => "Ruby"
// Negative indices must be calculated
string.substring(7, string.length - 1); // => "Ruby"
// We can use match to find substrings
string.match("Ruby")&[0]; // => "Ruby"
// If not found, match returns null, hence we guard with &
string.match("Python")&[0]; // => 0
// Match accepts both strings and regex
string.match(/R\w+/)&[0]; // => "Ruby"
// No match with regexp behaves the same as with strings
string.match(/P\w+/)&[0]; // => 0
As you can see the [] method is incredibly flexible as well as intuitive. JavaScript also provides decent alternatives, but gets clunky at times and in particular suffers from substr vs substring confusion.
History
The String#[] method has been pretty steady all the way back to Ruby's original release. The only evolution I could find was a subtle change to the return value when passing a single index. Prior to Ruby 1.9, this would return the numerical ASCII code of the character at that position (similar to String#ord), but from Ruby 1.9 onwards it returns a single-character string instead, making all the return values consistent.