【问题标题】:Cloning in Ruby via Marshaling not Working通过编组在 Ruby 中克隆不起作用
【发布时间】:2018-02-26 09:41:02
【问题描述】:

我正在为我的一个课程自学 Ruby,并且无法解决我遇到的错误。注意:我不是要求任何人为我做我的项目;只是想知道是否有人可以让我对此有所了解

要点:

  • 存在一个 Set 类,它有一个订阅者元素数组
  • Subscriber 类读取 .csv 文件并将新的 Subscriber 对象推送到 Set 对象的订阅者数组中
  • 我正在尝试查找任意两个集合的并集和交集
  • 使用封送处理,我能够让联合方法工作,但按照相同的设计,我无法让交集逻辑工作

Set 类的deepCopy 方法:

def deepCopy(toCopy)
  Marshal.load(Marshal.dump(toCopy))
end

Set 类的 union 方法(可行):

def union(set2)
  # clone the current set into union set
  unionSet = Set.new
  unionSet.deepCopy(self)

  # iterate through set 2 and append all unique elements to union set
  set2.subscribers.each do |sub|
    if !unionSet.subscribers.include?(sub)
      unionSet.subscribers.push(sub)
    end
  end
  unionSet.printSet
end

Set 类的 Intersection 方法(这不起作用):

def intersection(set2)
  intersectionSet = Set.new
  comparisonSet = Set.new
  otherSet = Set.new

  # choose the smallest set for the comparison set
  if @subscribers.size < set2.subscribers.size
    comparisonSet.deepCopy(self)
    otherSet.deepCopy(set2)
  else
    comparisonSet.deepCopy(set2)
    otherSet.deepCopy(self)
  end

  #PROBLEM: Both statements below print nothing and both say they are empty when checked. 
  intersectionSet.printSet
  comparisonSet.printSet

  # iterate through the comparison set and store all commonalities in intersection set
  comparisonSet.subscribers.each do |sub|
    puts "Looking for #{sub}"
    if otherSet.subscribers.include?(sub)
      intersectionSet.subscribers.push(sub)
    end
  end
  intersectionSet.printSet
end
end

这是一个非常基础的项目,但是学习 Ruby 的细微差别却让它变得相当困难。我什至尝试像在union 中那样在intersection 方法中克隆self,但这也不起作用。这让我想知道这是否是某种内存问题?

【问题讨论】:

  • 我建议将您的问题减少到最简单的可重现部分并相应地调整您的问题。您的代码示例不完整,没有得到充分解释。
  • @anothermnh 有什么具体的东西你觉得模糊吗?我试图避免发布整个源代码

标签: ruby marshalling deep-copy


【解决方案1】:

你没有在这里初始化你的集合:

  if @subscribers.size < set2.subscribers.size
    comparisonSet.deepCopy(self)
    otherSet.deepCopy(set2)
  else
    comparisonSet.deepCopy(set2)
    otherSet.deepCopy(self)
  end

返回的值未分配给集合。它应该类似于comparisonSet = self.deepCopy(self)。你可以看到这里的方法调用有多余的信息。我建议您将#deepCopy 更改为

def deep_copy  # use snake case as per ruby convention
  Marshal.load(Marshal.dump(self))
end

然后你可以这样做:

comparison_set = self.deep_copy
other_set = set2.deep_copy

您当前的实现与 union 一起使用,因为 union 集从一个空集开始,并接收您向其抛出的每个订阅者。

顺便说一句,我不确定您是否需要在此处进行复制。似乎你可以没有它。但是我当然没有看过你的全部代码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-26
    • 2020-10-24
    • 2016-06-21
    • 1970-01-01
    相关资源
    最近更新 更多