我现在正在代码学校学习,导师会给我们一份家庭作业,但我并没有真正得到它。你能救我吗?
因此,我们被要求通过类创建几何形状:
我已经开始编码,并创建了一个类Point,可访问坐标(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
例如,我想创建一个新的点类。所以:
p = Point.new
p.x = 1
p.y = 5
print p # -> #<Point:0x007f9463089cc0>
结果我有这样的事情:
#<Point:0x007f9463089cc0>
这是什么意思?
但如果我要求打印p.x和p.y - 那么我将得到一个可以理解的结果:
print p.x, ", ", p.y # -> 1, 5
我做错了什么或者如何在屏幕上理解这个结果?
拜托,我真的需要帮助来理解这个...
感谢您的帮助!
出现了另一个问题,在实际编程工作中是否有用于创建点,线和几何形状的东西?
答案 0 :(得分:1)
首先,你不需要设置者和吸气剂。我的意思是你不需要写这些方法:
def x=(value)
@x = value
end
def x()
@x
end
def y=(value)
@y = value
end
def y()
@y
end
您不需要这些方法的原因是您有这个电话:
attr_accessor :x, :y
并且该方法(attr_accessor)完全适合您。
其次,您可能希望在构造函数中允许一些灵活性,即,您的initialize方法允许传递x和y的值,并且如果没有传递则将它们默认为10。所以你可以这样做
def initialize(x = 10, y = 10)
@x = x
@y = y
end
这样,你就会得到这个:
p1 = Point.new
puts p.x # => 10
puts p.y # => 10
p2 = Point.new(15, 20)
puts p.x # => 15
puts p.y # => 20
注意p1的方法我没有传递任何参数,但x和y都按预期设置,这是因为我们在方法定义中为它们设置了默认值,这里:
def initialize(x = 10, y = 10)
现在,关于你为什么看到这个的问题:
p = Point.new
p.x = 1
p.y = 5
print p # -> #<Point:0x007f9463089cc0>
什么点:0x007fa003885bf8意味着你有一个Point类的实例(这是你在变量p中所拥有的)。默认情况下,当您尝试打印对象时,ruby将在对象上调用to_s方法,因为在您的情况下,您没有定义该方法,它将通过继承链来查看谁定义该方法。事实证明,该方法可以在Object类中找到(所有ruby对象都隐式继承自Object类),该方法的默认行为是打印类的名称,后跟实例在内存中的id,格式为:#(check :http://ruby-doc.org/core-2.3.1/Object.html#method-i-to_s)
如果要更改它,则可以将to_s方法覆盖为以下内容:
def to_s
"Point #{x},#{y}"
end
你会得到:
puts Point.new # => Point 10,10
希望有所帮助。
答案 1 :(得分:1)
没有错。 #<Point:0x007f9463089cc0>
仅表示它是对象标识为#<>
的类Point
的实例(0x007f9463089cc0
部分)。对象id是Ruby运行时用于查找每个对象的标识符,非常类似于内存地址。
虽然一切都很好,但Ruby中始终有一种方法可以减少代码。例如
class Point
attr_accessor :x, :y
def initialize(x = 10, y = 10)
@x, @y = x, y
end
end
甚至
Point = Struct.new(:x, :y)
答案 2 :(得分:0)
因为您宣布attr_accessor :x, :y
实际上你不需要为x和y定义getter和setter。
所以你的课程可以简化为
class Point
attr_accessor :x, :y
def initialize
@x = 10
@y = 10
end
end
您还可以向Point
添加方法to_s
class Point
attr_accessor :x, :y
def initialize
@x = 10
@y = 10
end
def to_s
"(#{x}, #{y})"
end
end
这样您就可以使用puts p
并在执行时获得ouptut (10, 10)
p = Point.new
puts p
(10, 10)
在这里,我更喜欢使用puts
而不是print
,因为它在输出后插入一个新的行字符,并且看起来更具可读性。
在to_s方法中,我使用ruby的字符串插值"#{}"
为你的点实例构建一个很好的输出。
答案 3 :(得分:0)
方法select
和print
输出puts
的结果,to_s
输出p
的结果。除非您覆盖这些方法,否则默认情况下,继承inspect
的自定义类会返回您获得的Object
形式。如果您想要其他输出,请覆盖这些方法,例如
#<class_name:object_id>