Dmitry Perfilyev wrote:
> Hi, I have next script:
> t.rb:
> ===========================
> class TestStr < String
>   attr_accessor :dupstr
>   def initialize ( str )
>     @dupstr = str
>     super(str)
>   end
> end
> ts=TestStr.new("aaa")
> puts ts.dupstr
> h=Hash.new()
> h[ts]=true
> puts h.keys.first.class
> puts h.keys.first
> puts h.keys.first.dupstr
> ===========================
> 
> run it:
> 
> $ ruby t.rb
> aaa
> TestStr
> aaa
> nil
> $
> 
> The question is - why there is 'nil' in the last line instead of "aaa" ?

It must be the T_STRING test in hash.c, an optimization, I assume.

VALUE
rb_hash_aset(hash, key, val)
    VALUE hash, key, val;
{
    rb_hash_modify(hash);
    if (TYPE(key) != T_STRING || st_lookup(RHASH(hash)->tbl, key, 0)) {
  st_insert(RHASH(hash)->tbl, key, val);
    }
    else {
  st_add_direct(RHASH(hash)->tbl, rb_str_new4(key), val);
    }
    return val;
}

You can still use your code as is, with this adjustment:

  require 'delegate'

  class TestStr < DelegateClass(String)
    # ...
  end

Also consider delegation as a primary strategy, not just as a workaround 
for this case.
-- 
Posted via http://www.ruby-forum.com/.