ruby - Define a method within a class which creates an instance of the class -


i'm writing class myhashset imitates set class. elements of set contained hash items reading {element => true}. here how defined:

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 

the last method union should such if type commands:

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") 

and try compute

set3=set1.union(set2) 

i should set3 variable, instance of myhashset such store is:

{"mark hamill"=>true, "harrison ford"=>true, "anthony daniels"=>true, "ewan mcgregor"=>true, "natalie portman"=>true} 

however, if try run undefined method error message:

`<main>': undefined method `union' #<myhashset:0x00000000f4e3b8> (nomethoderror) 

i don't understand why ruby not pick method.

you must use instance method not class method. , can use self.class.new insted of myhashset.new

like this

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 

output

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:

maybe can modify initialize method better usage this

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

after can call union easly

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

so final clas looks this

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