我有以下代码:
class MyGreeting
def initialize(name)
# Instance variables
@name = name
end
def say_hello
name.each do |x|
puts "Hello #{x}"
end
def say_bye
name.each do |x|
puts "Bye #{x}"
end
end
obj = MyGreeting.new([“johnny”, “kyle”, “sid”])
obj.say_hello
我正在尝试创建一个名为MyGreeter的类,它接收一个随后在类中使用的值数组。在上面的代码中,我有点展示了我的目标。我正在尝试使用方法say_hello输出“hello johnny”“hello kyle”hello sid“使用时。现在我收到一个我无法解决的错误。感谢任何帮助。
这是我收到的错误
syntax error, unexpected end-of-input, expecting keyword_end
答案 0 :(得分:1)
这里有一些问题,但最大的问题是你的缩进完全失控,需要解决。保持代码清洁有序非常重要,这样您就可以一目了然地发现错误,因此对于任何工作人员来说,结构都很明显。修复缩进会立即显示有大量缺少end
语句。
其次,你有“智能引号”,Ruby无法处理。如果您没有使用正确的代码编辑器,则可能需要关闭它们。
第三,如果你想在没有name
前缀的情况下引用它,你忘了将@
声明为必需的属性。
所有这一切,你得到了这个:
class MyGreeting
attr_reader :name
def initialize(name)
# Instance variables
@name = name
end
def say_hello
name.each do |x|
puts "Hello #{x}"
end
end
def say_bye
name.each do |x|
puts "Bye #{x}"
end
end
end
obj = MyGreeting.new(["johnny", "kyle", "sid"])
obj.say_hello
作为样式注释,如果变量隐式包含多个内容,则为其指定一个名称,表示像names
一样,这将是更好的选择。
答案 1 :(得分:1)
就像上面提到的Cary Swoveland一样,您需要end
来使用do
s。您还需要在name
方法中将@name
更改为say_
。
这是一个有效的版本:
class MyGreeting
def initialize(name)
# Instance variables
@name = name
end
def say_hello
@name.each do |x|
puts "Hello #{x}"
end
end
def say_bye
@name.each do |x|
puts "Bye #{x}"
end
end
end
obj = MyGreeting.new(["johnny", "kyle", "sid"])
obj.say_hello
答案 2 :(得分:0)
正如所指出的那样,适当的缩进将揭示不使用end
结束块的问题。
修复缩进后,我们收到以下错误:
`say_hello': undefined local variable or method `name' for #<MyGreeting:0x007f940c03ba90 @name=["johnny", "kyle", "sid"]> (NameError)
Did you mean? @name
这表示您在以下代码中使用的name
name.each do |x|
#...
end
是“未定义”,ruby认为它是局部变量或方法。
显然你打算将它作为@name
实例变量,所以你可以name
加@
作为前缀,nc.指出。
另一种解决方案是通过添加@name
方法为attr_reader
实例变量使用“getter方法”,如tadman所示。
class MyGreeting
attr_reader :name
# ...rest of the code omitted for brevity
end
请注意attr_reader :name
实际上是一种方法(及其参数),它与以下内容相同:
def name
@name
end
这是MyGreeting
实例变量的“getter方法”(它是@name
对象的实例方法),因为我们获取存储在其中的数据(@name
)对象(obj
)通过调用此方法。
如果您实施其中任何一项(例如,如果您添加attr_reader :name
或
def name
@name
end
),您不需要在@
之前添加name
,因为name
本身实际上是一种方法,在调用时会返回@name
。
希望这能让您更好地了解如何在Ruby中引用实例变量的值。
作为旁注,您可以使用“*”或"splat operator"将数组转换为方法的参数列表。它的工作原理如下:
def demo(arguments)
puts "arguments: #{arguments}"
end
demo(["foo", "bar"]) #=> arguments: ["foo", "bar"]
def demo_2(*arguments)
puts "arguments: #{arguments}"
end
demo_2("foo", "bar") #=> arguments: ["foo", "bar"]
注意,在demo_2
中,我们只是传入字符串对象,然后使用* (splat) operator将其转换为数组。当您不知道要将多少个参数传递给方法时,这尤其有用,在这种情况下,传递一个对象数组将不起作用,因为它的大小是固定的。
结合上面讨论的所有要点,您的原始代码可以重构如下:
class MyGreeting
attr_reader :names
def initialize(*names)
@names = names
end
def say_hello
names.each do |name|
puts "Hello #{name}"
end
end
def say_bye
names.each do |name|
puts "Bye #{name}"
end
end
end
obj = MyGreeting.new("johnny", "kyle", "sid")
obj.say_hello
## output:
# Hello johnny
# Hello kyle
# Hello sid