Most Concise Way to Test String Equality (Not Object Equality) for Ruby Strings or Symbols

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 if obj and other 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 if obj and other refer to the same hash key. This is used by Hash to test members for equality. For objects of class Object, eql? is synonymous with ==. Subclasses normally continue this tradition by aliasing eql? to their overridden == method, but there are exceptions. Numeric types, for example, perform type conversion across ==, but not across eql?, 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 ==, the equal? method should never be overridden by subclasses: it is used to determine object identity (that is, a.equal?(b) iff a is the same object as b).

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



Leave a reply



Submit