2016-06-07 69 views
0

我正在編寫模仿Set類的類MyHashSet。該組的元素被包含爲散列項目{element => true}。下面是它是如何定義的:在創建類的實例的類中定義方法

class MyHashSet 
    attr_accessor :store 
    def initialize 
    @store = {} 
    end 

    def insert(el) 
    @store.merge!(el => true) 
    end 

    def include?(el) 
    @store[el] 
    end 

    def delete(el) 
    @store.select! {|key,value| key != el} 
    end 

    def to_a 
    @store.keys 
    end 

    def self.union(set) 
    result=MyHashSet.new 
    result.store=(self.store).merge(set.store) 
    result 
    end 
end 

最後一個方法union應該是這樣的,如果我鍵入命令:

set1=MyHashSet.new 
set2=MyHashSet.new 

set1.insert("Mark Hamill") 
set1.insert("Harrison Ford") 
set1.insert("Anthony Daniels") 

set2.insert("Ewan McGregor") 
set2.insert("Natalie Portman") 
set2.insert("Anthony Daniels") 

,然後嘗試計算

set3=set1.union(set2) 

我應該得到一個set3變量,它是MyHashSet的一個實例,因此它的store是:

{"Mark Hamill"=>true, "Harrison Ford"=>true, "Anthony Daniels"=>true, "Ewan McGregor"=>true, "Natalie Portman"=>true} 

但是,如果我嘗試運行此我得到一個undefined method錯誤消息:

`<main>': undefined method `union' for #<MyHashSet:0x00000000f4e3b8> (NoMethodError) 

我不明白爲什麼Ruby沒有選擇這個方法。

+5

您使用的是**實例調用**類方法**。 – Aetherus

回答

0

您必須使用它像實例方法而不是類方法。您還可以使用self.class.new insted的的MyHashSet.new

這樣

class MyHashSet 
    attr_accessor :store 
    def initialize 
    @store = {} 
    end 

    def insert(el) 
    @store.merge!(el => true) 
    end 

    def include?(el) 
    @store[el] 
    end 

    def delete(el) 
    @store.select! {|key,value| key != el} 
    end 

    def to_a 
    @store.keys 
    end 

    def union(set) 
    result = self.class.new 
    result.store = self.store.merge(set.store) 
    result 
    end 
end 

輸出

set1=MyHashSet.new 
# => #<MyHashSet:0x1efea79 @store={}> 
set2=MyHashSet.new 
# => #<MyHashSet:0x34c75a @store={}> 

set1.insert("Mark Hamill") 
# => {"Mark Hamill" => true} 
set1.insert("Harrison Ford") 
# => {"Mark Hamill" => true, "Harrison Ford" => true} 
set1.insert("Anthony Daniels") 
# => {"Mark Hamill" => true, "Harrison Ford" => true, "Anthony Daniels" => true} 

set2.insert("Ewan McGregor") 
# => {"Ewan McGregor" => true} 
set2.insert("Natalie Portman") 
#=> {"Ewan McGregor" => true, "Natalie Portman" => true} 
set2.insert("Anthony Daniels") 
# => {"Ewan McGregor" => true, "Natalie Portman" => true, "Anthony Daniels" => true} 

set3 = set1.union(set2) 
# => #<MyHashSet:0x1c7cbad @store={"Mark Hamill"=>true, "Harrison Ford"=>true, "Anthony Daniels"=>true, "Ewan McGregor"=>true, "Natalie Portman"=>true}> 

BTW:

也許你可以修改爲更好的使用你的initialize方法這樣

def initialize(store = nil) 
    @store = store || {} 
end 

在這之後,你可以調用union伊斯利

def union(set) 
    self.class.new(self.store.merge(set.store)) 
end 

所以您的最終CLAS會看起來像這樣

class MyHashSet 
    attr_accessor :store 

    def initialize(store = nil) 
    @store = store || {} 
    end 

    def insert(el) 
    @store.merge!(el => true) 
    end 

    def include?(el) 
    @store[el] 
    end 

    def delete(el) 
    @store.select! { |key, value| key != el } 
    end 

    def to_a 
    @store.keys 
    end 

    def union(set) 
    self.class.new(self.store.merge(set.store)) 
    end 
end 
-1

我發現代碼的作品,如果我刪除「自我」。在「union」前面:

class MyHashSet 
    attr_accessor :store 
    def initialize 
    @store = {} 
    end 

    def insert(el) 
    @store.merge!(el => true) 
    end 

    def include?(el) 
    @store[el] 
    end 

    def delete(el) 
    @store.select! {|key,value| key != el} 
    end 

    def to_a 
    @store.keys 
    end 

    def union(set) 
    result=MyHashSet.new 
    result.store=(self.store).merge(set.store) 
    result 
    end 
end 

我想這是因爲該方法是在類的實例上而不是類本身上調用的。

+1

這是@Aetherus指出的,對嗎? –

+0

我建議在你的情況下使用'reject!'而不是'select!'。 –