传入一个Ruby类的数组

时间:2016-09-26 01:14:02

标签: arrays ruby

我有以下代码:

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

3 个答案:

答案 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