Project

General

Profile

Actions

Bug #9731

closed

Rails' HashWithIndifferentAccess is incompatible with Ruby's keyword arguments

Added by vrinek (Konstantinos Karachalios) about 10 years ago. Updated almost 5 years ago.

Status:
Closed
Assignee:
-
Target version:
-
ruby -v:
2.1.1
[ruby-core:61966]

Description

Origin: https://github.com/rails/rails/issues/14643

In Ruby it is possible to use a POR Hash in place of keyword arguments, making the transition between using an options = {} to keyword arguments easy.

The same is not true for HashWithIndifferentAccess and this makes it difficult to pass the params hash directly to methods with keyword arguments.

Bug test

require 'active_support/hash_with_indifferent_access'
require 'minitest/autorun'

def sum(a: 0, b: 0)
  a + b
end

class BugTest < MiniTest::Unit::TestCase
  def setup
    @normal_hash = {a: 18, b: 24} # just a hash
    @indiff_hash = ActiveSupport::HashWithIndifferentAccess.new(@normal_hash)
  end

  def test_ruby_hash
    assert_equal 42, sum(@normal_hash)
  end

  def test_hash_with_indifferent_access
    assert_equal 42, sum(@indiff_hash)
  end
end

Workaround

sum(@indiff_args.symbolize_keys)

VERSIONS

  • ruby 2.0.0-p353 & activesupport 4.0.1
  • ruby 2.1.0-p0 & activesupport 4.0.3
  • ruby 2.1.1-p76 & activesupport 4.0.4, 3.2.17

Related issues 4 (0 open4 closed)

Has duplicate Ruby master - Bug #9732: Rails' HashWithIndifferentAccess is incompatible with Ruby's keyword argumentsRejected04/11/2014Actions
Has duplicate Ruby master - Bug #9733: Rails' HashWithIndifferentAccess is incompatible with Ruby's keyword argumentsRejected04/11/2014Actions
Has duplicate Ruby master - Bug #9734: Rails' HashWithIndifferentAccess is incompatible with Ruby's keyword argumentsRejected04/11/2014Actions
Has duplicate Ruby master - Bug #9735: Rails' HashWithIndifferentAccess is incompatible with Ruby's keyword argumentsRejected04/11/2014Actions

Updated by mame (Yusuke Endoh) about 10 years ago

  • Has duplicate Bug #9732: Rails' HashWithIndifferentAccess is incompatible with Ruby's keyword arguments added

Updated by mame (Yusuke Endoh) about 10 years ago

  • Has duplicate Bug #9733: Rails' HashWithIndifferentAccess is incompatible with Ruby's keyword arguments added

Updated by mame (Yusuke Endoh) about 10 years ago

  • Has duplicate Bug #9734: Rails' HashWithIndifferentAccess is incompatible with Ruby's keyword arguments added

Updated by mame (Yusuke Endoh) about 10 years ago

  • Has duplicate Bug #9735: Rails' HashWithIndifferentAccess is incompatible with Ruby's keyword arguments added

Updated by rafaelfranca (Rafael França) about 10 years ago

Just to be clear this issue is not about HashWithIndifferentAccess, it is about using hash with string keys to be used as keyword arguments (HashWithIndifferentAccess store the keys as strings).

This same script would fail:

require 'minitest/autorun'

def sum(a: 0, b: 0)
  a + b
end

class BugTest < MiniTest::Unit::TestCase
  def setup
    @hash_with_symbol_keys = {a: 18, b: 24}
    @hash_with_string_keys = {'a' => 18, 'b' => 24}
  end

  def test_hash_with_symbol_keys
    assert_equal 42, sum(@hash_with_symbol_keys)
  end

  def test_hash_with_string_keys
    assert_equal 42, sum(@hash_with_string_keys)
  end
end

Updated by matz (Yukihiro Matsumoto) about 10 years ago

I am negative for the proposal. My opinion is that you should not (or no longer) use strings as keywords.
For transition purpose, ActiveSupport (or something else) can add a method to convert strings keys to symbol keys.

Matz.

Updated by rafaelfranca (Rafael França) about 10 years ago

Yes, I agree with you. I'm also not positive to changing keyword arguments to receive even strings and symbols, but I thought OP should request this feature here since it is not Rails specific, as he would have the same behavior with a normal hash using string keys.

As soon we only support Ruby 2.2 we can store the keywords as symbols, but until there, we can't change HashWithIndifferentAccess to use symbols or we are opening Rails applications to receive DDoS attacks.

We already have this method to convert strings keys to symbol keys. It is called symbolize_keys. And in my opinion it is fine to use if you know what is doing. I would never call symbolize_keys in request parameters for example. At least not until my application is running with the new symbol GC.

Updated by vrinek (Konstantinos Karachalios) about 10 years ago

I agree with the above comments. Probably waiting for Ruby 2.2 would be the best course of action here.

I will try nevertheless create a workaround by utilising Method#parameters to feed the usual params.slice(*args).symbolize_keys in a clever and unobstructive way. Hints/ideas are welcome.

Actions #9

Updated by jeremyevans0 (Jeremy Evans) almost 5 years ago

  • Status changed from Open to Closed
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0