Most concise way to test string equality (not object equality) for Ruby strings or symbols?
According to http://www.techotopia.com/index.php/Ruby_String_Concatenation_and_Comparison
Doing either
mystring == yourstring
or
mystring.eql? yourstring
Are equivalent.
Is == in Ruby always value equality?
In Ruby, ==
can be overloaded, so it could do anything the designer of the class you're comparing wants it to do. In that respect, it's very similar to Java's equals()
method.
The convention is for ==
to do value comparison, and most classes follow that convention, String
included. So you're right, using ==
for comparing strings will do the expected thing.
The convention is for equal?
to do reference comparison, so your test a.object_id == b.object_id
could also be written a.equal?(b)
. (The equal?
method could be defined to do something nonstandard, but then again, so can object_id
!)
(Side note: when you find yourself comparing strings in Ruby, you often should have been using symbols instead.)
Best Pattern to Indifferently Compare Strings/Symbols for Equality?
If you want to monkey patch the generic functionality in everywhere.
class Object
def to_s_equals? var
self.to_s == var
end
end
As mentioned, only convert symbols to strings, not strings to symbols unless you have a subsequent use for the symbol. You could be more specific and only do that on Symbol
Alternatively you could add something for String and Symbols, but I can't think of a good common name.
class Symbol
def equals_string? var
self.to_s == var
end
end
class String
def equals_symbol? var
self == var.to_s
end
end
Even then equals
isn't quite right, but match
infers a regex. homologous
maybe? (corresponding in structure, but not necessarily function)
I don't think your getting much brevity on to_s ==
. Maybe a bit of clarity enforcing the order you do the comparisons in.
What's the difference between equal?, eql?, ===, and ==?
I'm going to heavily quote the Object documentation here, because I think it has some great explanations. I encourage you to read it, and also the documentation for these methods as they're overridden in other classes, like String.
Side note: if you want to try these out for yourself on different objects, use something like this:
class Object
def all_equals(o)
ops = [:==, :===, :eql?, :equal?]
Hash[ops.map(&:to_s).zip(ops.map {|s| send(s, o) })]
end
end
"a".all_equals "a" # => {"=="=>true, "==="=>true, "eql?"=>true, "equal?"=>false}
==
— generic "equality"
At the Object level,
==
returns true only ifobj
andother
are the same object. Typically, this method is overridden in descendant classes to provide class-specific meaning.
This is the most common comparison, and thus the most fundamental place where you (as the author of a class) get to decide if two objects are "equal" or not.
===
— case equality
For class Object, effectively the same as calling
#==
, but typically overridden by descendants to provide meaningful semantics in case statements.
This is incredibly useful. Examples of things which have interesting ===
implementations:
- Range
- Regex
- Proc (in Ruby 1.9)
So you can do things like:
case some_object
when /a regex/
# The regex matches
when 2..4
# some_object is in the range 2..4
when lambda {|x| some_crazy_custom_predicate }
# the lambda returned true
end
See my answer here for a neat example of how case
+Regex
can make code a lot cleaner. And of course, by providing your own ===
implementation, you can get custom case
semantics.
eql?
— Hash
equality
The
eql?
method returns true ifobj
andother
refer to the same hash key. This is used byHash
to test members for equality. For objects of classObject
,eql?
is synonymous with==
. Subclasses normally continue this tradition by aliasingeql?
to their overridden==
method, but there are exceptions.Numeric
types, for example, perform type conversion across==
, but not acrosseql?
, so:1 == 1.0 #=> true
1.eql? 1.0 #=> false
So you're free to override this for your own uses, or you can override ==
and use alias :eql? :==
so the two methods behave the same way.
equal?
— identity comparison
Unlike
==
, theequal?
method should never be overridden by subclasses: it is used to determine object identity (that is,a.equal?(b)
iffa
is the same object asb
).
This is effectively pointer comparison.
check string for equality with multiple options
There's #include?
, but that's the other way round ([a,b,c].include?(c)
).
Comparing 2 arrays for content equality
It sounds like your Post class doesn't have a ==
operator of its own, so no two Post objects can be equal. I think you'll want to give Post some idea of equality.
With Ruby Booleans, what are you checking for if there are no equality statements?
This is a common paradigm in programming, not a Ruby abstraction. You are checking if something is truthy. In ruby in particular, everything is truthy except false
and nil
. Try it yourself in your console if you want to test this:
!!1 # => true
!!0 # => true
!![] # => true
!!{} # => true
...etc, whereas
!!false # => false
!!nil # => false
Important note: this is only the case for Ruby. Other languages have different rules. For example, in some languages 0
is falsy. It's important to learn these early on when learning a new language.
How can I test values for equality by using an array instead of chaining a gazillion ORs?
You the any?
method:
open_top_array = [12, 16, 99]
type = "Open top" if open_top_array.any?{ |n| cargo_operation_container_shifting[n] == 1 }
In Ruby, how to choose whether a symbol or string to be used in a given scenario?
a = :foo
b = :foo
a
and b
refer to the same object in memory (same identity)
a.object_id # => 898908
b.object_id # => 898908
Strings behave differently
a = 'foo'
b = 'foo'
a.object_id # => 70127643805220
b.object_id # => 70127643805200
So, you use strings to store data and perform manipulations on data (replace characters or whatnot) and you use symbols to name things (keys in a hash or something). Also see this answer for more use cases for symbol.
In ruby, how can I test input strings against a set of mixed data types?
You probably want to use ===
, which you can read as "kinda equals". It works for both strings and regexps as you would expect:
'100' === '100'
# true
/1\d\d/ === '100'
# true
For your arrays, you can use Regexp.union
which turns an array of strings into a regexp that matches any of those strings.
Related Topics
"Ago" Date/Time Functions in Ruby/Rails
Rails Routing (Root :To => ...)
Reading the First Line of a File in Ruby
How to Do Standard Deviation in Ruby
When Is It Better to Use a Struct Rather Than a Hash in Ruby
Adding an Instance Variable to a Class in Ruby
Building a Hash in a Conditional Way
All Possible Permutations of a Given String
How to Get Request's Target Controller and Action with Rails 3
Converting an Array of Keys and an Array of Values into a Hash in Ruby
Most Concise Way to Test String Equality (Not Object Equality) for Ruby Strings or Symbols
How to Use One Line Regular Expression to Get Matched Content
How to Validate Ssl Certificate Chain in Ruby with Net/Http
Rails: How to Autocomplete Search for Name But Save Id
How to Get Files Count in a Directory Using Ruby
Why Does Foreman Not Output Some Things Until I Press Control-C