Feature #14680
closedAdding +@ and -@ to hash and array
Added by kddnewton (Kevin Newton) over 6 years ago. Updated almost 6 years ago.
Description
Since we have -@
and +@
for strings and it's very useful (and reads better than .freeze
) I'd like to propose adding the same API to hash and array. Especially with constants, linters are always telling me to freeze them, and I'd like to be able to accomplish that with -@
. I've attached the necessary code to make that happen.
Files
freeze.patch (3.86 KB) freeze.patch | kddnewton (Kevin Newton), 04/11/2018 02:49 PM |
Updated by shevegen (Robert A. Heiler) over 6 years ago
I like .dup
and .freeze
, more than +
and -
on class String
.
https://ruby-doc.org/core-2.5.0/String.html#method-i-2B-40
The only good thing is that I don't have to use any of these
methods so ultimately I don't have to care either way. :)
As for linters, I assume you refer to rubocop since that is
by far the most common use case I could see, with people
putting things such as:
FOO = 'foo'.freeze
BAR = 'bar'.freeze
into files. I wonder if matz thinks that this is a good way;
to me, I always wondered when people do so. Probably
lint-based development ... should that not be superfluous
with frozen strings now? One comment on top of the file
and avoid all the explicit .freeze
calls?
Updated by kddnewton (Kevin Newton) over 6 years ago
I don't think it's as common these days to see .freeze
all over the place, since the linters explicitly tell you to use the frozen string literal comment. But that's explicitly for literals. There are plenty of cases where you'd want to freeze strings without them being a literal in the code. In this case there's also plenty of occurrences where you'd want to freeze hashes and arrays without them beings literals. Maybe I should have rephrased the ticket, it's definitely not just for the benefit of lint-based development.
Updated by nobu (Nobuyoshi Nakada) over 6 years ago
- Subject changed from Adding @+ and @- to hash and array to Adding +@ and -@ to hash and array
- Description updated (diff)
Updated by rab (Rob Biedenharn) over 6 years ago
If -@
is supposed to return a frozen copy, is that patch really doing that? The tests don't seem to ensure that. Do rb_hash_freeze
and rb_ary_freeze
make copies first or .freeze
the given object?
Updated by kddnewton (Kevin Newton) over 6 years ago
This patch is adding -@
and +@
to array and hash, mirroring the logic of string's version of those methods. So for -@
if the array or hash is already frozen, it just returns the object, otherwise it returns a frozen copy of it. The opposite for +@
.
Updated by rab (Rob Biedenharn) over 6 years ago
My question is whether this would pass:
def test_uminus
a = { a: 1, b: 2, c: 3 }
refute a.frozen?
assert (-a).frozen?
a = { a: 1, b: 2, c: 3 }.freeze
assert_equal a, -a
# * If the hash is frozen, then return the hash itself.
fa = { a: 1, b: 2, c: 3 }.freeze
assert_equal fa, -fa
assert_equal fa.object_id, (-fa).object_id
# * If the hash is not frozen, return a frozen copy of it.
ua = { a: 1, b: 2, c: 3 }
assert_equal ua, -ua
refute_equal ua.object_id, (-ua).object_id
end
as the code simply return rb_hash_freeze(hsh);
when not OBJ_FROZEN(hsh)
.
Updated by Hanmac (Hans Mackowiak) over 6 years ago
we need to specify it, that -@
and +@
are not doing deep freeze (they don't freeze the values of hash or elements of array)
people might do this:
VAL = -["abc"]
and suspect the string inside the array to be frozen too
or are we asume now that frozen-string-literal is true for this?
Updated by kddnewton (Kevin Newton) over 6 years ago
Happy to specify it in the docs, but it would be odd to assume that it did since .freeze
itself doesn't.
Updated by matz (Yukihiro Matsumoto) almost 6 years ago
- Status changed from Open to Closed
The +@
and -@
for strings are strongly coupled with frozen-string-literals
magic comment. Since we don't have frozen-array-expression
nor frozen-hash-expression
magic comments, I don't think we have a strong reason for +@
and -@
methods for arrays and hashes.
Matz.