【问题标题】:Ruby: Calling a method from another method that needs an attributeRuby:从另一个需要属性的方法调用方法
【发布时间】:2021-07-17 23:20:35
【问题描述】:

基本上,我有两个方法和一个数组。我正在设置一个 CLI 界面。我有一种方法“调用”,它贯穿其他方法。一种这样的方法需要一个论据。所有这些方法都在同一个类中。

class CLI

  array = ["test"]

  def method_2
    method_1
  end

  def method_1(array)
    puts array
  end

end

我希望上面输出数组。但是,当我调用类的新实例时,我得到错误数量的参数。我不知道在哪里添加所需的参数。

感谢您的宝贵时间。

-M

【问题讨论】:

  • method_1 需要一个参数,所以你在method_2 中调用method_1 是错误的。你想做什么?
  • 我有几个方法需要从“method_2”调用,但我需要先弄清楚如何调用一个方法。我希望 method_2 调用 method_1,并希望 method_1 显示数组(或任何其他变量)
  • array = ["test"] 应该是什么?一个常数?实例变量?类变量?
  • 只是一个字符串作为占位符。对不起,我是新手。我认为这并不重要。

标签: ruby class oop methods arguments


【解决方案1】:

通常在面向对象的设计中,您将数据和作用于对象中的数据的方法封装起来。在 Ruby 中,您可以使用实例变量来创建对象的属性:

class CLI
  def initialize(array = [])
    @array = []
  end

  def method_2
    method_1
  end

  def method_1
    puts @array
  end
end

cli = CLI.new(["Hello", "World"])
cli.method2  

实例变量使用印记@。它们被认为是私有的,因为即使 Ruby 不使用 private 关键字作为实例变量,它们也仅限于实例。

类也可以有实例变量:

class CLI
  @array = ["Hello", "World"]

  def self.hello
    puts @array.join(" ")
  end

  def you_cant_access_it_from_an_instance
    @array
  end
end

CLI.hello # Hello World
CLI.new.you_cant_access_it_from_an_instance # nil

这是一个属于类本身的“类”实例变量——它不与子类共享。这很有效,因为在 Ruby 中,类是对象 - Class 类的实例。

Ruby 还具有在一个类及其所有后代之间共享的类变量:

class Foo

  @@array = ["Hello", "World"]
    
  def self.hello
    puts @@array.join(" ")
  end

  def self.array=(val)
    @@array = val
  end
end

class Bar < Foo; end
Bar.array = ['Oh', 'noes']
Foo.hello # Oh noes

它们在线程安全方面存在严重问题,最好避免出现意外行为。

我相信你正在做的一个常见模式是工厂方法,它使用其输入创建一个新实例,然后调用它的调用方法:

class CLI
  def initialize(*args)
    @args = args
  end

  def call
     puts @args.inspect
     # do something awesome
  end

  # factory method thats basically just a convenience
  def self.call(*args)
    new(args).call
  end
end

CLI.call(*ARGV) # passes the command line arguments

【讨论】:

    【解决方案2】:

    我不清楚你想要做什么,但听起来你想要至少有一个(或多个)方法来打印出变量的当前值,但是您不想在调用这些方法时将该变量作为参数传递给它们。

    您无法通过定义默认参数来实现这一点(例如def method_1(array=['test']),因为该默认参数仅在定义方法时评估一次,并且该默认值将永远是第一次定义方法时的值(它没有得到更新)。

    所以把你的代码改成这样:

    class CLI
    
      @@array = ["test"]
    
      def method_2
        method_1
      end
    
      def method_1
        puts @@array
      end
    
    end
    

    @@ 前缀表示一个类变量:该类的所有实例将共享该变量的相同值。然后确保@@array 的值保持最新。您可能想重新设计您的程序,但除了风格和最佳实践之外,总有一个适合您的答案。

    执行此操作的正常方法是在调用时将参数传递给method_1,但如果您希望method_2 调用method_1 而您不想将其作为参数传递给@ 987654328@,那你就别无选择了(这就是为什么我说你可能想重新设计你的界面)。

    【讨论】:

      猜你喜欢
      • 2020-03-03
      • 1970-01-01
      • 2012-01-24
      • 1970-01-01
      • 1970-01-01
      • 2014-10-07
      • 1970-01-01
      • 1970-01-01
      • 2011-06-01
      相关资源
      最近更新 更多