I've got the following logic in my code:
if [email protected]?(p.name)
...
end
@players is an array. Is there a method so I can avoid the !?
Ideally, this snippet would be:
if @players.does_not_include?(p.name)
...
end
I've got the following logic in my code:
if [email protected]?(p.name)
...
end
@players is an array. Is there a method so I can avoid the !?
Ideally, this snippet would be:
if @players.does_not_include?(p.name)
...
end
if @players.exclude?(p.name)
...
end
ActiveSupport adds the exclude? method to Array, Hash, and String. This is not pure Ruby, but is used by a LOT of rubyists.
require 'active_support/core_ext/enumerable'Here you go:
unless @players.include?(p.name)
...
end
You might have a look at the Ruby Style Guide for more info on similar techniques.
if flag unless @players.include?(p.name) is awkward and if flag && [email protected]?(p.name) uses negation.if let only true pass the condition, unless lets pass false and nil. This sometimes lead to hard to find bugs. Therefore I prefer exclude?Looking at Ruby only:
TL;DR
Use none? passing it a block with == for the comparison:
[1, 2].include?(1)
#=> true
[1, 2].none? { |n| 1 == n }
#=> false
Array#include? accepts one argument and uses == to check against each element in the array:
player = [1, 2, 3]
player.include?(1)
#=> true
Enumerable#none? can also accept one argument in which case it uses === for the comparison. To get the opposing behaviour to include? we omit the parameter and pass it a block using == for the comparison.
player.none? { |n| 7 == n }
#=> true
!player.include?(7) #notice the '!'
#=> true
In the above example we can actually use:
player.none?(7)
#=> true
That's because Integer#== and Integer#=== are equivalent. But consider:
player.include?(Integer)
#=> false
player.none?(Integer)
#=> false
none? returns false because Integer === 1 #=> true. But really a legit notinclude? method should return true. So as we did before:
player.none? { |e| Integer == e }
#=> true
How about the following:
unless @players.include?(p.name)
....
end
module Enumerable
def does_not_include?(item)
!include?(item)
end
end
Ok, but seriously, the unless works fine.
unless it's ok for the snippet showed, but the condition may be more complex. I think it's handy to have these negated methods, they allow more declarative code.Try this, it's pure Ruby so there's no need to add any peripheral frameworks
if @players.include?(p.name) == false do
...
end
I was struggling with a similar logic for a few days, and after checking several forums and Q&A boards to little avail it turns out the solution was actually pretty simple.
Using unless is fine for statements with single include? clauses but, for example, when you need to check the inclusion of something in one Array but not in another, the use of include? with exclude? is much friendlier.
if @players.include? && @spectators.exclude? do
....
end
But as dizzy42 says above, the use of exclude? requires ActiveSupport
I was looking up on this for myself, found this, and then a solution. People are using confusing methods and some methods that don't work in certain situations or not at all.
I know it's too late now, considering this was posted 6 years ago, but hopefully future visitors find this (and hopefully, it can clean up their, and your, code.)
Simple solution:
if not @players.include?(p.name) do
....
end
not to substitute !. Been using Ruby for 15 years and that's new to me. Thanks for posting!
dovalid ruby? i get an errorsyntax error, unexpected end-of-input(works if i remove thedo)