 <p>Looking at the source of <a href="http://www.ruby-doc.org/stdlib-2.1.1/libdoc/set/rdoc/Set.html#method-c-new" rel="nofollow"><code>Set::new</code></a>:</p> <pre><code># File set.rb, line 80 def initialize(enum = nil, &amp;block) # :yields: o @hash ||= Hash.new enum.nil? and return if block do_with_enum(enum) { |o| add(block[o]) } else # you did not supply any block, when you called `new` # thus else part will be executed here merge(enum) end end </code></pre> <p>it seems that <code>Set.new</code> calls method <code>#add</code> internally. In the OP's example, <code>block</code> is <code>nil</code>, thus <a href="http://www.ruby-doc.org/stdlib-2.1.1/libdoc/set/rdoc/Set.html#method-i-merge" rel="nofollow"><code>#merge</code></a> is called:</p> <pre><code># File set.rb, line 351 def merge(enum) if enum.instance_of?(self.class) @hash.update(enum.instance_variable_get(:@hash)) else # in your case this else part will be executed. do_with_enum(enum) { |o| add(o) } end self end </code></pre> <p>Hence <code>add</code> is called for each element of <code>enum</code> (<code>[1,2]</code>). Here, you overrode the original <code>#add</code> method, and within that method, you are calling the old <code>#add</code> method with the argument <code>5</code>.</p> <p>Set implements a collection of <strong>unordered values with no duplicates</strong>. Thus even if you added <code>5</code> twice, you are getting only one <code>5</code>. This is the reason you are not getting <code>#&lt;Set: {1,2}&gt;</code>, but <code>#&lt;Set: {5}&gt;</code>. As below, when you call <code>Set.new</code>, the object <code>#&lt;Set: {5}&gt;</code> is created just as I explained above:</p> <pre><code>require 'set' class Set alias :old_add :add def add(arg) arg = 5 old_add arg end end s = Set.new ([1,2]) s # =&gt; #&lt;Set: {5}&gt; </code></pre> <p>When you called <code>s.add(3)</code>, your overridden <code>add</code> method was called, and it again passed the <code>5</code> to the old <code>add</code> method. As I said earlier, <code>Set</code> doesn't contain duplicate values, thus the object will still be the same as the earlier <code>#&lt;Set: {5}&gt;</code>.</p>