【问题标题】:How to call instance variables from one function to another function in same class?如何将实例变量从一个函数调用到同一类中的另一个函数?
【发布时间】:2022-01-27 21:28:47
【问题描述】:

实际上我是 ruby​​ 中 oops 概念的新手,在这里我想将实例变量从一个函数调用到同一类中的另一个函数。但是我得到了第二个函数“one_object”的未定义方法

module User
    class Object
        class << self
            def add_object(items)
                @data={}
                @data.merge!(items)
            end 
            # i want to use above @data = {} for next one_object method after adding items to the add_object method
            def one_object
                @data.merge!({"ext"=>"1.0"})
            end
        end
    end 
end
a = User::Object.add_object({"txt"=>"text_file","csv"=>"csv_file"})
p a.one_object

预期输出:

{"txt"=>"text_file", "csv"=>"csv_file", "ext"=>"1.0"}

【问题讨论】:

  • 如果您是 OOP 新手,您可能应该从定义一个带有一些实例方法的临时类开始,而不是直接跳入 class &lt;&lt; self 兔子洞 ;-)
  • 是的,谢谢你的建议,你能分享一些这方面的知识吗,我的意思是你能提供解决方案吗。
  • @Bharath 为什么首先在上面的 sn-p 中添加class &lt;&lt; self?它正在做一些“魔法”,在您熟悉一些基础知识之前最好不要碰它(这根本不是魔法,但它确实需要对 Ruby 对象模型有更深入的了解)。创建一个简单的类来完成必要的工作,然后在必要时进一步移动......
  • @KonstantinStrukov 现在我更新了我的代码。所以我尝试使用带有类的模块,你能提供解决方案吗?事情就在这里,我得到了“add_object”方法的答案,但我还需要使用下一个方法的最终输出
  • Object 是一个现有的类,也许你可以为你的类想出另一个名字。

标签: ruby


【解决方案1】:

您将add_object 的结果分配给a(即您的a 现在是一个哈希),但接下来您将在a 上调用one_object(但one_object 是@ 的一部分987654327@ 而不是您的 Hash 实例)。

如果您向add_object 添加另一行,包含self,您将收到预期的输出。

随着更改,add_object 将返回 User::Object,您不会遇到最初的问题。

【讨论】:

  • 另外:虽然这不是您的问题的一部分,但我高度假设您希望 add_object 的第一行阅读 @data||={}。目前在您的问题中编写的方式,您不会添加对象(正如方法名称所暗示的那样),而是在每次调用该方法时替换数据。
【解决方案2】:

在 Ruby 中,Object 是所有对象的根类。虽然您可以在 User 中拥有自己的 Object 类,但这可能会引起很多混乱。

让我们通过删除User 模块(与示例无关)并将Object 重命名为Foo(您会找到更好的名称)来简化您的问题。要初始化实例变量,您可以使用initialize 方法,每次通过new 构造对象时默认调用该方法:

class Foo
  def initialize
    @data = {}
  end
end

foo = Foo.new
#=> #<Foo:0x00007fb551823d78 @data={}>
#                            ^^^^^^^^

您分配给@data 的哈希值将在所有实例方法之间共享。此外,每个Foo 实例都有自己的@data 哈希。要将merge! 另一个哈希放入其中,您可以使用:

class Foo
  def initialize
    @data = {}
  end

  def add(hash)
    @data.merge!(hash)
  end
end

foo = Foo.new
#=> #<Foo:0x00007fbc80048230 @data={}>

foo.add({"abc"=>123})
#=> {"abc"=>123}

foo.add({"def"=>456})
#=> {"def"=>456}

foo
#=> #<Foo:0x00007fbc80048230 @data={"abc"=>123, "def"=>456}>

为了链接多个add 调用(所谓的fluent interface),您必须从方法中返回self

class Foo
  def initialize
    @data = {}
  end

  def add(hash)
    @data.merge!(hash)
    self # <- like this
  end
end

foo = Foo.new
#=> #<Foo:0x00007ff7408003d8 @data={}>

foo.add({"abc"=>123}).add({"def"=>456})
#=> #<Foo:0x00007ff7408003d8 @data={"abc"=>123, "def"=>456}>

最后,要添加静态数据,您可以简单地调用自己的方法:

class Foo
  def initialize
    @data = {}
  end

  def add(hash)
    @data.merge!(hash)
    self
  end

  def add_more
    add({"more" => 789})
  end
end

foo = Foo.new
#=> #<Foo:0x00007f99b20f8590 @data={}>

foo.add({"abc"=>123}).add({"def"=>456}).add_more
#=> #<Foo:0x00007f99b20f8590 @data={"abc"=>123, "def"=>456, "more"=>789}>

【讨论】:

  • 感谢分享知识,一个问题你解开了我的几个答案
猜你喜欢
  • 2017-11-04
  • 1970-01-01
  • 2019-04-07
  • 1970-01-01
  • 1970-01-01
  • 2022-07-08
  • 1970-01-01
  • 2021-04-23
  • 1970-01-01
相关资源
最近更新 更多