We were asked to create geometric shapes via classes. We must create:
I created a Point class, with accessible coordinates (2D):
class Point
attr_accessor :x, :y
def initialize
@x = 10
@y = 10
end
def x=(value)
@x = value
end
def x()
@x
end
def y=(value)
@y = value
end
def y()
@y
end
end
And, I want to create a new point class:
p = Point.new
p.x = 1
p.y = 5
print p # -> #<Point:0x007f9463089cc0>
And, as a result, I have some thing like this:
#<Point:0x007f9463089cc0>
What does this mean?
If I print px, py
then I will have a understandable result:
print p.x, ", ", p.y # -> 1, 5
How can I understand this result on the screen?
Is there any use in a real programming job to create point, lines and geometric shapes?
You don't need to write the setters and getters methods:
def x=(value)
@x = value
end
def x()
@x
end
def y=(value)
@y = value
end
def y()
@y
end
This is because you can use:
attr_accessor :x, :y
and attr_accessor
does that for you.
You might want to allow some flexibility in your constructor. Your initialize
method allows passing the values for x
and y
and will default to 10 if nothing is passed, so you can do this:
def initialize(x = 10, y = 10)
@x = x
@y = y
end
This way, you will get this:
p1 = Point.new
puts p.x # => 10
puts p.y # => 10
p2 = Point.new(15, 20)
puts p.x # => 15
puts p.y # => 20
Notice how for p1
I don't pass any arguments and yet x
and y
both get set as expected because we are setting a default value for them in the method definition, here:
def initialize(x = 10, y = 10)
Regarding your question about why you see this:
p = Point.new
p.x = 1
p.y = 5
print p # -> #<Point:0x007f9463089cc0>
Point:0x007fa003885bf8
means that you have an instance of the class Point
in your variable p
. By default Ruby will call the to_s
method on an object when you try to print it, since in your case you didn't define that method it will go through the inheritance chain to see who defines that method. It turns out that that method is found in the Object class which all Ruby objects implicitly inherit from, and that method's default behaviour is to print the name of the class followed by the instance's ID in memory, in the format:
#<ClassName:MemoryID>
See: http://ruby-doc.org/core-2.3.1/Object.html#method-i-to_s
If you want to change that then you can override to_s
to something like this:
def to_s
"Point #{x},#{y}"
end
That way you will get:
puts Point.new # => "Point 10,10"
There's nothing wrong.
#<Point:0x007f9463089cc0>
simply means that it is an instance (the #<>
part) of class Point
with an object ID of 0x007f9463089cc0
. An object ID is an identifier for Ruby's interpreter to find each object, very much like a memory address.
Though everything is okay, there is always a way in Ruby that leads to less code. For example:
class Point
attr_accessor :x, :y
def initialize(x = 10, y = 10)
@x, @y = x, y
end
end
Or even:
Point = Struct.new(:x, :y)
Because you are declaring attr_accessor :x, :y
you actually don't need to define a getter and setter for x
and y
, so your class can be simplified to:
class Point
attr_accessor :x, :y
def initialize
@x = 10
@y = 10
end
end
Also you can add a to_s
method to Point:
class Point
attr_accessor :x, :y
def initialize
@x = 10
@y = 10
end
def to_s
"(#{x}, #{y})"
end
end
so you can use puts p
and get as ouptut (10, 10)
when you do:
p = Point.new
puts p
(10, 10)
I prefer to use puts
instead of print
because it insert a new-line character after the output, and it looks more readable. In to_s
I'm using Ruby's string interpolation "#{}"
to build a nice output for your Point instance.
Methods print
and puts
output the result of to_s
, and p
outputs the result of inspect
. Unless you overwrite these methods, by default, a custom class that inherits Object
returns the form #<class_name:object_id>
that you got. If you want some other output, overwrite these methods, for example
class Point
def to_s
"#@x,#@y"
end
end
...
print p
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.