Bug #13799
closedENV.dup returns a plain Object
Description
I was doing ENV.dup to get a copy of the environment that can be modified without affecting ENV. However, ENV.dup returns a plain Object
irb(main):005:0> ENV.dup
=> #<Object:0x00000002024fc0>
irb(main):006:0> ENV.dup['PATH']
NoMethodError: undefined method `[]' for #<Object:0x000000020446e0>
from (irb):6
from /home/doudou/.rbenv/versions/2.4.1/bin/irb:11:in `<main>'
irb(main):007:0>
The only way I found to get a copy is Hash[ENV]
Updated by Hanmac (Hans Mackowiak) over 6 years ago
the Problem:
ENV is an Hash-like Object with having singleton methods to look like an Hash, but isn't one
dup does make a copy of an object of the same class, in that case useless because you don't want an Object and the singleton methods are not copied
what you can do is using ENV.to_h which does return an Hash as you want
Updated by sylvain.joyeux (Sylvain Joyeux) over 6 years ago
Fair enough.
In this case, I would ideally expect #dup to not exist at all (since the result is not what #dup is expected to return, which is a functional copy of the receiver), or at least raise.
Updated by shevegen (Robert A. Heiler) over 6 years ago
Interesting.
https://ruby-doc.org/core-2.4.1/ENV.html does not mention #dup so perhaps this comes
from Hash or some other upstream object?
I also can not quite think of a use case for .dup there, perhaps someone can explain
why ENV has it?
On a side note, does anyone know why the documentation above does not mention #dup?
Updated by nobu (Nobuyoshi Nakada) over 6 years ago
- Status changed from Open to Rejected
You have to use clone
to copy singleton methods.
http://ruby-doc.org/core-2.4.1/Object.html#method-i-dup-label-on+dup+vs+clone
But the subject of ENV
is only one per process, it's useless.
Updated by sylvain.joyeux (Sylvain Joyeux) over 6 years ago
Understood. But what about removing 'dup' and 'clone' from ENV altogether ?
The fact that ENV is an object with singleton methods is an implementation detail. ENV is obviously meaningful if there is only one per process, but right now does accept the dup and clone methods. It would be a lot less confusing if the object would refuse being duped or cloned ...