I'm reading Comparable module.
And trying to see where Comparable
module itself is implemented, but I can’t find it anywhere.
I only see places where it gets added using include
.
Isn't that the module should have its implementation provided elsewhere? So that you just do a plug and play by using include
?
Or is that in the following code:
class Geeksforgeeks
# include comparable module
include Comparable
attr :name
def <=>(other_name) # LineA
name.length <=> other_name.name.length # LineB
end
def initialize(name)
@name = name
end
end
LineA: is something at the Geeksforgeeks
class level.
LineB: is something at Integer (Length) level.
If that's the case then where is <=>
written for Integers?
EDIT:
My code builds without include Comparable
. I'm just not so sure what it means though:
class Geeksforgeeks
# does not include Comparable
attr :name
def <=>(other_name) # LineA
name.length <=> other_name.name.length # LineB
end
def initialize(name)
@name = name
end
end
jack = Geeksforgeeks.new('jack')
pete = Geeksforgeeks.new('pete')
alexander = Geeksforgeeks.new('Alexander')
def areSameGeeks(g1, g2)
if g1 <=> g2
puts 'equal'
else
puts 'not equal'
end
end
areSameGeeks(jack,pete) # equal
areSameGeeks(jack, jack) # equal
areSameGeeks(jack, alexander) # equal
Like why are all three, returning 'equal'?
CodePudding user response:
And trying to see where
Comparable
module itself is implemented, but I can’t find it anywhere.
Comparable
is part of the core library of whatever Ruby implementation you are using. For example:
- in Rubinius,
Comparable
is implemented incore/comparable.rb
, - in TruffleRuby, it is implemented in
src/main/ruby/truffleruby/core/comparable.rb
, - in MRuby, it is implemented in
mrblib/compar.rb
, - in Opal, it is implemented in
opal/corelib/comparable.rb
, - in JRuby, it is implemented in
core/src/main/java/org/jruby/RubyComparable.java
, - in IronRuby, it is implemented in
Src/Libraries/Builtins/Comparable.cs
, and - in YARV, it is implemented in
compar.c
.
However, I personally find it not so much interesting where something is implemented but rather where it is specified. Comparable
is specified in section 15.3.3 Comparable
of the ISO/IEC 30170:2012 Information technology — Programming languages — Ruby specification. A less formal specification is given in core/comparable/
of The Ruby Spec Suite aka ruby/spec
.
It is also described in The Ruby Programming Language by David Flanagan and Yukihiro 'matz' Matsumoto, Programming Ruby by Dave Thomas, Andy Hunt, and Chad Fowler, and of course in the Ruby documentation
If that's the case then where is
<=>
written for Integers?
Integer#<=>
is part of the core library of whatever Ruby implementation you are using. For example:
- in Rubinius,
Integer#<=>
is implemented incore/integer.rb
, - in TruffleRuby, it is implemented in
src/main/java/org/truffleruby/core/numeric/IntegerNodes.java
, - in MRuby, it is implemented in
src/numeric.c
which delegates tocmpnum
, - in Opal, it technically does not exist (this is one of the few instances where Opal is not compliant with the Ruby Language Specification) because Opal does not have Ruby
Float
s orInteger
s, it only has ECMAScriptnumber
s; for those,Number#<=>
is implemented inopal/corelib/number.rb
, - in JRuby,
Integer
is an abstract class, so it only has a declaration ofInteger#<=>
incore/src/main/java/org/jruby/RubyInteger.java
, the actual implementations are in the two subclassesFixnum
(core/src/main/java/org/jruby/RubyFixnum.java#L1043-L1060
) andBignum
(core/src/main/java/org/jruby/RubyBignum.java
), - in IronRuby, it is implemented in
Src/Libraries/Extensions/ClrInteger.cs
(at least forInteger
s that fit into a C#int
) and just delegates to C#'sint.CompareTo
, and - in YARV, it is implemented in
numeric.c
and delegates to eitherfix_cmp
orbig_cmp
(defined inbignum.c
).
However, I personally find it not so much interesting where something is implemented but rather where it is specified. Integer#<=>
is specified in section 15.2.8.3.6 Integer#<=>
of the ISO/IEC 30170:2012 Information technology — Programming languages — Ruby specification. A less formal specification is given in core/integer/comparison_spec.rb
of The Ruby Spec Suite aka ruby/spec
.
It is also described in The Ruby Programming Language by David Flanagan and Yukihiro 'matz' Matsumoto, Programming Ruby by Dave Thomas, Andy Hunt, and Chad Fowler, and of course in the Ruby documentation.
CodePudding user response:
<=>
isn't implemented within the Comparable
module:
https://ruby-doc.org/core-3.1.1/Comparable.html
This operation is implemented within each Ruby type (for example - String, Array, Integer). For default Ruby types it is possible to compare only objects of the same type, if you will try to compare it with something different you will get the nil value.
In your example LineA is a method for objects of Geeksforgeeks class, so you can use it as gfg_object <=> other_gfg_object
. By the way your implementation of <=>
isn't quite correct, it should checks that other_name
is an instance of Geekforgeeks
class (or another type) and return nil
if it isn't. Correct example:
def <=>(object)
if object.is_a? Geekforgeeks
return name.length <=> object.name.length
elif object.is_a? String
return name.length <=>object.length
else
return nil
end
end