Reputation: 3191
Coming from Python I find the following behaviour very surprising:
irb(main):211:0> x= 33
=> 33
irb(main):212:0> x[0]
=> 1
irb(main):213:0> x[1]
=> 0
irb(main):214:0> x[2]
=> 0
Is there a rationale/philosophy for not raising an error in this example?
Upvotes: 2
Views: 369
Reputation: 211560
You might be a little confused about what this is doing internally, but that's normal when dealing with Ruby because it's quite unlike other scripting languages. Unless you've used SmallTalk it might even seem insane.
When Ruby sees the following code:
x = 6
x[1]
What it's actually doing is this:
x.send(:[], 6) # Send :[] method call to x with arguments [ 6 ]
The x
object is free to interpret that however it wants, and the behaviour is typically (though not always) defined by the class x
belongs to if x
is a normal instance.
In this case it's returning the bit at a given index, equivalent to x & (1 << 6) >> 6
.
Sometimes the []
method does several things:
string = "brackets"
# Retrieve a single character
string[1]
# => "r"
# Retrieve a substring
string[5,2]
# => "et"
# Perform a pattern match
string[/[^aeiou]+/]
# => "br"
This also does some pretty crazy things since you can apply it to a Proc as well:
fn = lambda { |x| x + 1 }
# Conventional (explicit) call
fn.call(2)
# => 3
# Square bracket method
fn[5]
# => 6
Since Ruby leans very heavily on Duck Typing, this means that you can write a Proc to fill in where you'd normally have a Hash or an Array and the method receiving your object is none the wiser.
It's this flexibility in leaving the meaning of x[...]
for your own class instance x
up to you that makes it pretty powerful.
For example:
class Bracketeer
def [](i)
"%d brackets" % i
end
end
bracketeer = Bracketeer.new
bracketeer[6]
# => "6 brackets"
This simple notation often comes in handy when you're trying to create a minimal interface for a class of yours. In many cases you can use something simple like []
to replace what would be a more verbose method like find_by_id
or cache_fetch
.
Upvotes: 4
Reputation: 2672
It is returning the n'th bit as rightfully observed by @msergeant.
What this means is, for the number 33, its binary representation is:
Index : [7][6][5][4] [3][2][1][0]
Bits : 0 0 1 0 0 0 0 1
Which explains the output:
irb(main):212:0> x[0]
=> 1
irb(main):213:0> x[1]
=> 0
irb(main):214:0> x[2]
=> 0
Upvotes: 1
Reputation: 16331
Certainly. You'll find that the manual is quite illuminating.
This is returning the binary bit for the bit position value as a zero or one.
Upvotes: 1
Reputation: 4801
The bracket operator gives you the nth bit of the binary representation:
http://ruby-doc.org/core-2.1.2/Fixnum.html#method-i-5B-5D
Upvotes: 5