They both create a shallow copy of an object (meaning that they don’t copy the objects that might be referenced within the copied object). However, #clone does two things that #dup doesn’t:

  • copy the singleton class of the copied object
  • maintain the frozen status of the copied object

Examples of the singleton methods not being copied.

dup:

a = Object.new def a.foo; :foo end p a.foo # => :foo b = a.dup p b.foo # => undefined method `foo’ for #<Object:0x007f8bc395ff00> (NoMethodError)

vs clone:

a = Object.new def a.foo; :foo end p a.foo # => :foo b = a.clone p b.foo # => :foo

Frozen state:

a = Object.new

a.freeze 

p a.frozen? # => true 

b = a.dup 

p b.frozen? # => false 

c = a.clone 

p c.frozen? # => true

Because of the extra steps, clone is a bit slower than dup but that’s probably not what will make your app too slow.