Ruby新手在这里。以下代码不起作用。
class Shows
def echo
x, y, z = self
puts x
puts y
puts z
end
end
["Foo", 2, 2001].echo
这样做。
class Array
def echo
x, y, z = self
puts x
puts y
puts z
end
end
["Foo", 2, 2001].echo
我的理解是我可以通过
使Show成为Arrays的继承class Shows < Arrays
但这也不起作用。
我知道我可以创建一个方法并像这样使用它
def echo(x, y, c)
puts x
puts y
puts z
end
然而,我想在第一段代码中这样做是有原因的。
答案 0 :(得分:2)
在第一段代码中,当#echo
上未定义echo
时,您构建了一个数组,然后尝试在其上调用Array
。您更接近于将Array
子类化的想法,但您仍需要实例化Shows
实例,而不是Array
实例!
你可以这样做:
# Create a new class called Shows, which is a subclass of Array
class Shows < Array
def echo
# In this case, since self is an Array subclass structure, you can use
# destructuring assignment to assign to x, y, and z
x, y, z = self
puts x
puts y
puts z
end
end
# Create a new Shows instance, passing in an array of values that should populate it.
# This works because Shows#initialize inherits from Array#initialize, which accepts an
# array as an input value.
Shows.new(["Foo", 2, 2001]).echo
答案 1 :(得分:0)
第一位代码无法工作的原因是["Foo", 2, 2001]
的类是一个数组。如果你编写一些代码来初始化一个show对象,那么你可以使用它的唯一方法就是它。例如,您可以执行以下操作:
s = Show.new("Foo", 2, 2001)
s.echo
要做到这一点,需要这样的事情:
class Show
def initialize(name, day, year)
@name = name
@day = day
@year = year
end
def echo
puts @name
puts @day
puts @year
end
end
这很有效,因为现在您将创建一个新的show对象,然后在该对象上调用show。另外,作为一种最佳实践,我通常会建议您不要在ruby中编辑Array类(或字符串,int ...),因为它会让事情变得混乱。
答案 2 :(得分:0)
Ruby中继承的好处是,层次结构中较低的类(或“子类”)可以访问(或“继承”)更高级别的类的功能。子类还可以添加自己的特定功能。
请考虑以下代码:
class Shows
def echo
x, y, z = self
puts x
puts y
puts z
end
end
["Foo", 2, 2001].echo # => NoMethodError: undefined method `echo' for ["Foo", 2, 2001]:Array
[]
语法是一个数组文字。它相当于Array.new
。因此,这个:
["Foo", 2, 2001] # => ["Foo", 2, 2001]
["Foo", 2, 2001].class # => Array
可能会像这样写得更乏味:
a = Array.new # => []
a << "Foo" # => ["Foo"]
a << 2 # => ["Foo", 2]
a << 2001 # => ["Foo", 2, 2001]
a.class # => Array
我只向您展示这个较长的版本,以便更容易看到这一点:
["Foo", 2, 2001].echo
正在将echo
邮件发送到班级Array
的对象,但echo
仅在班级Shows
中定义。
同样,以下代码也遇到同样的问题:
class Shows < Array
def echo
x, y, z = self
puts x
puts y
puts z
end
end
["Foo", 2, 2001].echo # => NoMethodError: undefined method `echo' for ["Foo", 2, 2001]:Array
虽然班级Shows
现在继承了班级Array
的所有功能,但我们绝不会将echo
讯息发送到班级Shows
的对象 - 我们将消息发送到类Array
的对象。
因此,只有您下面的示例才会按您期望的方式运行:
class Array
def echo
x, y, z = self
puts x
puts y
puts z
end
end
["Foo", 2, 2001].echo # => Foo
# => 2
# => 2001
在某些情况下,继承类似Array
的核心Ruby类并不一定是错误的决定。你应该在了解后果的情况下做到这一点。看看这篇文章:Beware subclassing Ruby core classes, by Steve Klabnik。