Ruby: toggle a boolean inline?
How can I get the opposite of a boolean in Ruby (I know that it is converted to 0/1) using a method inline?
say I have the given开发者_StackOverflow社区 instance:
class Vote
def return_opposite
self.value
end
end
Which obviously doesn't do anything, but I can't seem to find a method that is simple and short something like opposite()
or the like. Does something like this exist and I'm just not looking at the right place in the docs? If one doesn't exist is there a really short ternary that would toggle it from 1 => 0 or 0 => 1?
I like to use this
@object.boolean = !@object.boolean
Boolean expressions are not 0
or 1
in Ruby, actually, 0
is not false
If n is numeric we are swapping 0 and 1...
n == 0 ? 1 : 0 # or...
1 - n # or...
[1, 0][n] # or maybe [1, 0][n & 1] # or...
class Integer; def oh_1; self==0 ? 1:0; end; end; p [12.oh_1, 0.oh_1, 1.oh_1] # or...
n.succ % 2 # or...
n ^= 1
If b already makes sense as a Ruby true or false conditional, it's going to be hard to beat:
!b
These examples differ in how they treat out-of-range input...
You can use XOR operator (exclusive or)
a = true
a # => true
a ^= true
a # => false
a ^= true
a # => true
Edit: See comment by @philomory below.
I believe this is basically an oversight in the boolean classes (TrueClass and FalseClass) in Ruby.
You can negate any object:
nil.! => true
false.! => true
true.! => false
0.! => false
1.! => false
a.! => false (all other objects)
But you cannot in-place negate the boolean objects:
a.!! => does not compile
I guess this would call for trouble with the compiler's grammar.
The best you can do, is thus:
a = a.!
If you just want to access the opposite of the value, use !
as some people have said in the comments. If you want to actually change the value, that would be bool_value = !bool_value
. Unless I've misunderstood your question. Which is quite possible.
In order to toggle a boolean data in rails you can do this vote.toggle!(:boolean)
If you want to toggle boolean (that is false
and true
) , that would be as simple as just use !
as others has stated.
If you want to toggle between 0
and 1
, I can only think of something naive as below :)
def opposite
op = {0=>1,1=>0}
op[self.value]
end
In a Rails app, I use this method to toggle a post between paused and active, so ! (not) is my preferred method.
def toggle
@post = Post.find(params[:id])
@post.update_attributes paused: !@post.paused?
msg = @post.paused? ? 'The post is now paused.' : 'The post is now active.'
redirect_to :back, notice: msg
end
I think that using a ternary can be interesting :
check = false
check == true ? check = false : check = true
精彩评论