- Creating Hash - all the options
a)
[12] pry(main)> {a: 1, b: 2}
=> {:a=>1, :b=>2}
b)
Hash.new(0) # this sets default value to 0
c)
[10] pry(main)> Hash[:a, 1, :b, 2]
=> {:a=>1, :b=>2}
How is the Hash[]
implemented?
It's easy!
class Hash
def self.[](*args)
h = {}
0.step(args.length-1, 2) do |i|
h[args[i]] = args[i+1]
end
h
end
end
- Creating an array
a)
[1, 2, 3]
b)
[27] pry(main)> Array.new(5, 'ar')
=> ["ar", "ar", "ar", "ar", "ar"]
c)
[33] pry(main)> Array('a')
=> ["a"]
How is the Array()
implemented?
It's easy!
module Kernel
def MyOwnArray(*args)
args
end
end
- Creating a class
a)
class MyOwnHash < Hash; end
b)
MyOwnHash = Class.new(Hash)
MyOwnHash = Class.new(Hash) do
def show_me_keys
keys
end
class << self
def new(*args)
args
end
end
- Returning different class
I want my object initializer to return different class. Impossible?
class Hash
def initialize(*args)
return []
end
end
[9] pry(main)> Hash.new
=> {}
[6] pry(main)> Struct.new(:login)
=> #<Class:0x007fc5fccb94f8>
[7] pry(main)> _.class == Struct
=> false
initialize
is an instance method, it is run on an object after it's created. How about this?
class Hash
def self.new(*args)
return []
end
[12] pry(main)> Hash.new('a', 'b')
=> []
end
- Cloning object
There are 2 methods to clone object: dup and clone. While both seem to have the same behaviour, they differ a bit:
[1] pry(main)> module A; end
=> nil
[2] pry(main)> a = Object.new.extend(A)
=> #<Object:0x007ff1de023848>
[3] pry(main)> a.is_a? A
=> true
[4] pry(main)> a.dup.is_a? A
=> false
[5] pry(main)> a.clone.is_a? A
=> true
[6] pry(main)>
Bonus: Subclassing a class
[122] pry(main)> MyClass = Class.new(Class)
TypeError: can't make subclass of Class