Это - лучшая практика никогда для использования бросков C-стиля по трем главным причинам:
, Поскольку palm3D отметил:
я нахожу синтаксис броска в стиле С++ слишком подробным.
Это является намеренным по причинам, приведенным выше.
синтаксис конструктора (официальное название: бросок функционального стиля), семантически тот же как бросок C-стиля и должен избежаться также (за исключением переменных инициализаций на объявлении), по тем же причинам. Это спорно, должно ли это быть верно даже для типов, которые определяют пользовательских конструкторов, но в Эффективном C++, Meyers утверждает, что даже в тех случаях необходимо воздержаться от использования их. Проиллюстрировать:
void f(auto_ptr<int> x);
f(static_cast<auto_ptr<int> >(new int(5))); // GOOD
f(auto_ptr<int>(new int(5)); // BAD
static_cast
здесь будет на самом деле звонить auto_ptr
конструктор.
It is expected behaviour (across all ruby versions). And if you experiment a bit further, you'll see that you always access the same hash, no matter which key you use:
>> a[:a][:b] = 1
=> 1
>> a[:c][:d] = 2
=> 2
>> a[:d]
=> {:b=>1, :d=>2}
The way Hash.new with a default argument works is: If you do hash[key]
it checks whether that key exists in the hash. If it does, it returns the value for that key. If not it returns the default value. It does not add the key to the hash and it will return the same default object (not a copy) every time.
To get what you want, you want to specify a default block instead. That way, the block will be executed every time you access a key that is not in the hash. Inside the block you can create a new Hash and set the key to "point" to that hash. Like so:
Hash.new { |h,k| h[k] = {} }