I have two variables which sometimes contain double data structure value. How can I determine in Ruby that a variable is having double value?
For example,
a = 3.4
a.is_a_double #=> true
a = "dadadad#asdasd.net"
a.is_a_double #=> false?
You should be able to use any of following method to know this:
is_a?
kind_of?
instance_of?
See uses:
2.2.2 :009 > a = 4.5
=> 4.5
2.2.2 :010 > a.is_a? Float
=> true
2.2.2 :011 > a.kind_of? Float
=> true
2.2.2 :015 > a.instance_of? Float
=> true
Related
In languages like Java and C#, if you are override equality operators, you must override the hash method as well.
Whenever a.equals(b), then a.hashCode() must be same as b.hashCode()
As far I understand, some internal data structures in these languages rely on the condition above to hold true in order to function correctly.
I wonder if the same is true in Ruby. Do you need to override hash method of the object when overriding == operator? I heard that you need to override the eql? when overriding ==. What are the reasons behind those claims, and what would happen if you won't override those?
No, you don't need to override eql? and hash methods.
However, as tadman mentioned, you should override them. You don't know how eql? might be used, and if you don't override hash then you will get strange results if you use the object as a hash key. See this blog post.
Having said all that, you brought up an interesting point:
In Java and C#, you must override the hash method as well.
What happens if you don't override the hash method? Will it fail to compile, or is it a poor practice?
It feels like in Ruby there are very few hard and fast rules like this. I wonder if Ruby has a different paradigm compared to languages like C#, Java and C++. Perhaps the paradigm is different because Ruby is duck typed and does not have a separate compile process.
Ruby has 3 equality methods ==, eql? and equal?. At the base Object class they all do the same, but for the more specific classes they provide class-specific semantics.
What they compare is dependant on the developer who implemented the class, but nevertheless, there is a convention.
== — Value comparison
True when two objects have the same value.
2.2.3 :011 > 5 == 5.0
=> true
2.2.3 :012 > 'test' == 'test'
=> true
2.2.3 :013 > { a: 10 } == { a: 10.0 }
=> true
2.2.3 :014 > :test == :test
=> true
2.2.3 :016 > ['a', :test, 10] == ['a', :test, 10.0]
=> true
eql? — Value and type comparison
True when two objects have the same value and type
2.2.3 :028 > 'test'.eql? 'test' # Strings
=> true
2.2.3 :029 > 5.eql? 5 # Fixnums
=> true
2.2.3 :030 > 5.eql? 5.0 # Fixnum & Float
=> false
2.2.3 :032 > { a: 10 }.eql?({ a: 10 }) # Hash
=> true
2.2.3 :033 > { a: 10 }.eql?({ a: 10.0 })
=> false
equal? — Reference comparison
True when two objects share the same memory reference. This method should never be overridden.
2.2.3 :017 > 'test'.equal? 'test'
=> false
# Each string is an independent object even if they share content
2.2.3 :018 > :test.equal? :test
=> true
# Symbols share reference if they have the same content
2.2.3 :019 > 1.equal? 1
=> true
2.2.3 :020 > [].equal? []
=> false
2.2.3 :021 > a = 'test'
=> "test"
2.2.3 :022 > b = a # b is a reference to the same object as a
=> "test"
2.2.3 :023 > b.equal? a
=> true
If you are just overriding the == you don't need to override the hash method, but you should, in case the eql? or equal? methods get called.
So I tried searching with different keywords but either I'm a bad search-operator or It's too simple of a problem. Either way my problem is that I can't get my head around this logic in Ruby.
x = 5
x = x + 1
So if I understood it correctly x becomes 6. Why is that? if you "reassign" the value literally doesn't it become "x + 1" without having anything to do with the first line.
Thanks.
Operators are applied in order of their precedence.
It's not that the right side is (always) evaluated first, it's that addition has higher precedence than assignment. Run irb to test.
$ irb
2.2.0 :001 > x # => the variable 'x' doesn't yet exist.
NameError: undefined local variable or method `x' for main:Object
from (irb):1
from /home/mike/.rvm/rubies/ruby-2.2.0/bin/irb:11:in `'
2.2.0 :002 > x = 5 # => Assign x the value 5.
=> 5 # => Evaluating the expression 'x = 5' returns 5
2.2.0 :003 > x # => and the value of 'x' is 5.
=> 5
2.2.0 :004 > x = x + 1 # => Addition has higher precedence than
# => assignment. Ruby evaluates 'x + 1', then
# => assigns the result to 'x', and finally
# => returns the result.
=> 6
2.2.0 :005 > x # => 'x' has the same value as the previous
# => result.
=> 6
2.2.0 :006 > x + 1 # => This expression returns the value 7.
=> 7
2.2.0 :007 > x # => But without the assignment operator (=),
=> 6 # => the value of 'x' didn't change.
Why is this important? Because operator precedence doesn't always work the way you think it ought to.
$ irb
2.2.0 :001 > true and false # => That makes sense.
=> false
2.2.0 :002 > x = true and false # => That *seems* to make sense, but
=> false
2.2.0 :003 > x # => 'x' has the value true, because
=> true # => assignment has higher
# => precedence than Boolean 'and'.
2.2.0 :004 > x = (true and false)
=> false
2.2.0 :005 > x
=> false
2.2.0 :006 >
Most people expect the expression x = true and false to be equivalent to x = (true and false), because they expect Ruby to always evaluate the right side first. But Ruby doesn't do that. It evaluates assignment (=) before Boolean and. So the expression x = true and false is actually equivalent to (x = true) and false.
Ruby's precedence table on SO
The right side is evaluated first
Ruby itself will give you an object_id for each of them and you could possibly use this to identify all your objects. But there’s a little gotcha:
x = 'matz'
=> "matz"
y = 'matz'
=> "matz"
[ x.object_id, y.object_id ]
=> [2164843460, 2134818480]
So Ruby interpreter identify the object_id and assign value in that memory place
interpreter starts with the operator having the highest precedence
I discovered this behavior of multi_json ruby gem:
2.1.0 :001 > require 'multi_json'
=> true
2.1.0 :002 > sym = :symbol
=> :symbol
2.1.0 :003 > sym.class
=> Symbol
2.1.0 :004 > res = MultiJson.load MultiJson.dump(sym)
=> "symbol"
2.1.0 :005 > res.class
=> String
Is this an appropriate way to store ruby symbols? Does JSON provide some way to distinguish :symbol from "string"?
Nope is the simple answer. Most of the time it only really matters for hashes and there's a cheat on hashes, symbolize_keys!. Bottom line is that JSON does not understand symbols, just strings.
Since you are using MultiJson, you can also ask MultiJson to do this for you...
MultiJson.load('{"abc":"def"}', :symbolize_keys => true)
I came across this ruby object_id allocation question sometime back and then read this awesome article which talks about VALUE and explains why object_id of true, nil and false the way they are. I have been toying with ruby2.0 object_id when I found the apparent change that has been made regarding object_id of true and nil.
forbidden:~$ ruby -v
ruby 2.0.0p0 (2013-02-24 revision 39474) [x86_64-linux]
forbidden:~$
forbidden:~$ irb
irb(main):001:0> true.object_id
=> 20
irb(main):002:0> false.object_id
=> 0
irb(main):003:0> nil.object_id
=> 8
irb(main):004:0> exit
forbidden:~$
forbidden:~$ rvm use 1.9.3
Using /home/forbidden/.rvm/gems/ruby-1.9.3-p392
forbidden:~$ ruby -v
ruby 1.9.3p392 (2013-02-22 revision 39386) [x86_64-linux]
forbidden:~$
forbidden:~$ irb
irb(main):001:0> true.object_id
=> 2
irb(main):002:0> false.object_id
=> 0
irb(main):003:0> nil.object_id
=> 4
tl;dr: The values for true and nil were respectively 2, 4 in 1.9.3 and 1.8.7, but have been changed to 20, 8 in ruby2.0.0 - even though the id of false remains the same i.e. 0 and the ids for Fixnum maintains the same old 2n+1 pattern.
Also, the way Fixnum and Bignum are implemented is still the same in 2.0.0 as the example given in the above mentioned article also runs just the same way it used to:
irb(main):001:0>
irb(main):002:0* ((2**62)).class
=> Bignum
irb(main):003:0> ((2**62)-1).class
=> Fixnum
irb(main):004:0>
What's the reason behind this object_id change?
Why was this change made? How is this going to help developers?
A look at the Ruby source where these values are defined suggests that this has something to do with “flonums” (also see the commit where this was introduced). A search for ”flonum” came up with a message on the Ruby mailing list discussing it.
This is a technique for speeding up floating point calculations on 64 bit machines by using immediate values for some floating point vales, similar to using Fixnums for integers. The pattern for Flonums is ...xxxx xx10 (i.e. the last two bits are 10, where for fixnums the last bit is 1). The object_ids of other immediate values have been changed to accomodate this change.
You can see this change by looking at the object_ids of floats in Ruby 1.9.3 and 2.0.0.
In 1.9.3 different floats with the same value are different objects:
1.9.3p385 :001 > s = 10.234
=> 10.234
1.9.3p385 :002 > t = 10.234
=> 10.234
1.9.3p385 :003 > s.object_id
=> 2160496240
1.9.3p385 :004 > t.object_id
=> 2160508080
In 2.0.0 they are the same:
2.0.0p0 :001 > s = 10.234
=> 10.234
2.0.0p0 :002 > t = 10.234
=> 10.234
2.0.0p0 :003 > s.object_id
=> 82118635605473626
2.0.0p0 :004 > t.object_id
=> 82118635605473626
On this page http://swtch.com/~rsc/regexp/regexp3.html it says that RE2 supports named expressions.
RE2 supports Python-style named captures (?P<name>expr), but not the
alternate syntaxes (?<name>expr) and (?'name'expr) used by .NET and
Perl.
ruby-1.9.2-p180 :003 > r = RE2::Regexp.compile("(?P<foo>.+) bla")
#=> #<RE2::Regexp /(?P<foo>.+) bla/>
ruby-1.9.2-p180 :006 > r = r.match("lalal bla")
#=> #<RE2::MatchData "lalal bla" 1:"lalal">
ruby-1.9.2-p180 :009 > r[1] #=> "lalal"
ruby-1.9.2-p180 :010 > r[:foo]
TypeError: can't convert Symbol into Integer
ruby-1.9.2-p180 :011 > r["foo"]
TypeError: can't convert String into Integer
But I'm not able to access the match with the name, so it seems like a useless implementation. Am I missing something?
Looking at your code output, it seems that you are using the Ruby re2 gem which I maintain.
As of the latest release (0.2.0), the gem does not support the underlying C++ re2 library's named capturing groups. The error you are seeing is due to the fact that any non-integer argument passed to MatchData#[] will simply be forwarded onto the default Array#[]. You can confirm this in an irb session like so:
irb(main):001:0> a = [1, 2, 3]
=> [1, 2, 3]
irb(main):002:0> a["bob"]
TypeError: can't convert String into Integer
from (irb):2:in `[]'
from (irb):2
from /Users/mudge/.rbenv/versions/1.9.2-p290/bin/irb:12:in `<main>'
irb(main):003:0> a[:bob]
TypeError: can't convert Symbol into Integer
from (irb):3:in `[]'
from (irb):3
from /Users/mudge/.rbenv/versions/1.9.2-p290/bin/irb:12:in `<main>'
I will endeavour to add the ability to reference captures by name as soon as possible and update this answer once a release has been made.
Update: I just released version 0.3.0 which now supports named groups like so:
irb(main):001:0> r = RE2::Regexp.compile("(?P<foo>.+) bla")
=> #<RE2::Regexp /(?P<foo>.+) bla/>
irb(main):002:0> r = r.match("lalal bla")
=> #<RE2::MatchData "lalal bla" 1:"lalal">
irb(main):003:0> r[1]
=> "lalal"
irb(main):004:0> r[:foo]
=> "lalal"
irb(main):005:0> r["foo"]
=> "lalal"