-3

I have a Ruby class that compares the size of two values of x and y by inheriting the built-in module Comparable and sqrt methods. But unfortunately, I don't understand what def scalar in the code is calculating?

In the example below, Ruby's execution results in that v1 is greater than v2, but if I print the results of v1 and v2 alone, I get nothing but nonsense. So my second question is, what are the resulting values for v1 and v2?

class Vector
  include Comparable              
  attr_accessor :x, :y

  def initialize(x, y)
    @x, @y = x, y
  end

  def scalar
    Math.sqrt(x ** 2 + y ** 2)  
  end

  def <=> (other)                 
    scalar <=> other.scalar
  end
end

v1 = Vector.new(2, 6)
v2 = Vector.new(4, -4)
puts v1         #=> #<Vector:0x000055a6d11794e0>
puts v2         #=> #<Vector:0x000055a6d1179490>
p v1 <=> v2     #=> 1
p v1 < v2       #=> false
p v1 > v2       #=> ture

TPR
  • 101
  • 6
  • 3
    `#` isn't nonsense. It's showing the class (Vector) and the memory address (0x000055a6d11794e0) that uniquely identifies that object in Ruby's heap. None of the code here is mutating the values `v1` and `v2` so they are identical to what they were when constructed. – Max Feb 14 '22 at 16:54
  • 1
    Do you know what a vector is in mathematics? If not, I suggest you learn about them before trying to use them in code. – Code-Apprentice Feb 14 '22 at 17:31
  • 1
    To get a better understanding of your code, try `puts v1.scalar` and `puts v2.scalar`. Since the result of this calculation is used for the comparison, it is much more useful than just `puts v1` and `puts v2`. – Code-Apprentice Feb 14 '22 at 17:35
  • Also : see [Math::hypot](https://ruby-doc.org/core-3.1.0/Math.html#method-c-hypot). – steenslag Feb 14 '22 at 19:39
  • 2
    TPR, if you execute `require 'matrix'` you'll be in trouble because, among other things it loads an existing class [Vector](https://ruby-doc.org/stdlib-2.4.0/libdoc/matrix/rdoc/Vector.html) (at least in some Ruby versions). Be careful to avoid class names that are used by Ruby. – Cary Swoveland Feb 14 '22 at 21:00

3 Answers3

2

Math.sqrt(x ** 2 + y ** 2) is using good old Pythagoras to calculate the Cartesian distance of the vector's endpoint from the origin, i.e., the length of the vector. For v1 this is 6.324555320336759, and for v2 the result is 5.656854249492381.

To inspect a Ruby object use p rather than puts.

p v2   # <Vector:0x0000000109a1eb40 @x=4, @y=-4>
pjs
  • 18,696
  • 4
  • 27
  • 56
1

what are the resulting values for v1 and v2?

Override to_s

class Vector 
  def to_s
    "x = #{x} : y = #{y} : scalar = #{'%.6f' % scalar}"
  end
end #Vector

And you get this output:

puts v1    # =>  x = 2 : y = 6 : scalar = 6.324555
puts v2    # =>  x = 4 : y = -4 : scalar = 5.656854
radarbob
  • 4,964
  • 2
  • 23
  • 36
  • 1
    Probably not a good idea. The OP can see the instance variables and method results by other means and this result would likely just lead to additional confusion. – engineersmnky Feb 14 '22 at 23:13
  • I think it's a great idea to output the attributes state in a user-controlled formatted way, and "to string" is a great place to do it. I love taking advantage of the implied call aspect. I've found it to be very helpful over the years. If the OP needs referential object equality then put that in there too! That would be super! Without contradicting myself I agree that there are "... other means" for outputting various aspects of an object. – radarbob Feb 14 '22 at 23:51
  • I wonder if potential confusion is mitigated by the fact(?) that `Vector` could be immutable and `scalar` method can become a intiialize-time-calculation instance variable. – radarbob Feb 14 '22 at 23:52
  • So it would be better to override `inspect`? ruby-docs Object.inspect => *User defined classes should override this method to provide a better representation of obj.* – radarbob Feb 19 '22 at 23:43
  • Yes that would better however `inspect` conventionally represents state so it would not show the return value of `scalar`, just `@x` and `@y` – engineersmnky Feb 20 '22 at 04:08
0

scalar would be better named magnitude because it is calculating the length of a vector using the Pythagorean Theorem. If you are unfamiliar with vectors and Pythagorean Theorem, I suggest you study the mathematical concepts here before you continue with much more code. Those concepts will be critical in understanding how they are used in code.

Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268