Q1. But I am not sure what .[] part is doing.
Almost everything is an object in Ruby, and we can define a method on anything that's an object. So []=
is a method defined on the Hash
class (an object) in Ruby, just like +
and -
are methods on numbers (also objects):
> 4 + 5
# => 9
> 4.+(5)
# => 9
> 10.-(3)
# => 7
Likewise, we can call the .[]
or .[]=
methods for objects that define it, like an Array:
> arr = ['hi', 'there', 'welcome', 'to', 'StackOverflow']
> arr.[](3)
# => "to"
or like your Hash:
> hash = {:name => 'Bob', :age => 27}
> hash[:name]
# => "Bob"
> hash[:name] = 'Steve'
# => "Steve"
Again, Ruby lets us put methods on anything that's an object, and (almost) everything is an object in Ruby. So we can define that .[]
method on any class we like:
> class Foo
> def [](arg)
> arg
> end
> end
> Foo.new[456]
> # => 456
Since instances of objects are also objects, we can define that method to be only on specific instances:
> h = {} # a Hash instance
> def h.[](arg) # we're giving this instance a new method
> "received #{arg}"
> end
> h[123]
# => "received 123"
Other instances of the same class won't get that implementation:
> {:foo => :bar}[123] # other Hash instances don't have this method,
# so they're using the default Hash#[] method
# => nil
.[]
is something of a special case in one respect, because we let you skip the parentheses and put the argument right inside the brackets:
> arr[3] == arr.[](3)
# => true
Q2. Can you use [] or other non-alphabets in a Ruby method name?
No, you can't use []
in the name of an arbitrary Ruby method. This is an operator (like +
or -
in the previous example).
You can only overload specific operators, namely (listed in order of precedence):
!
, ~
, +
(unary)
**
-
(unary)
*
, /
, %
+
, -
(binary)
<<
, >>
&
|
, ^
<
, <=
, =>
, >
==
, ===
, !=
, =~
, !~
, <=>
Otherwise, a Ruby method can contain any mixture of alphanumeric Unicode characters and underscores. (I'm using "alphanumeric" loosely here -- Ruby is very liberal in what it allows, and generally speaking any character that isn't otherwise reserved by the language to tokenize things will work.) It may optionally end with a single !
or ?
, and it may not start with a number.
So these are valid method names:
present?
valid_user?
replace!
replace
更换
(but you probably should make your method names using the A-Z Latin alphabet so developers don't hate you)
❨╯°□°❩╯︵┻━┻
┬─┬ノ❨º_ºノ❩
replace_all
REPLACE_1
REPLACE_ALL
Note that while the last two are valid method names, by convention Rubyists usually reserve ALL-CAPS identifiers for constants, not methods.