0

This is a before_action in a controller:

def map_params
  Rails.logger.error "[before] #{params.inspect}"
  if false
    params = { :hi => :there }
  end
  Rails.logger.error "[after] #{params.inspect}"
end

This is an output:

[before] <ActionController::Parameters ...>
[after] nil

Interestrngly enough, if I comment out the params assignment it will behave differently:

[before] <ActionController::Parameters ...>
[after] <ActionController::Parameters ...>

Why is it happening?

alexb
  • 880
  • 11
  • 16

1 Answers1

2

Because you introduce params local variable (even though you don't initialize it), which has identical name to params method. If you refer to params as params() or self.params (to tell Ruby interpreter that you're refering to method, not variable), you will see your ActionController::Parameters in both cases.

Marek Lipka
  • 50,622
  • 7
  • 87
  • 91
  • 1
    Or `self.params` – Sergio Tulentsev Oct 31 '17 at 10:45
  • Thanks! I didn't know that Ruby has variable hoisting. So the question is not relevant to Rails at all... – alexb Oct 31 '17 at 10:51
  • @Sandrik: the variable is not hoisted. Unlike ECMAScript, for example, it does *not* exist before it is defined. It *is*, however, defined at *parse time*, not at runtime. This is explained better and in much more detail in several of the dozens of duplicates of this question (which is one of the reasons why duplicate questions shouldn't be answered (or even better yet, shouldn't be asked in the first place) but instead be closed so that the knowledge doesn't end up fragmented all over the site). – Jörg W Mittag Oct 31 '17 at 11:00
  • @JörgWMittag got it, if it was hoisted, the output would be `nil` in both cases. As for your (very reasonable btw) remark, I did try to find duplicates, but I couldn't find any because I didn't know what the actual problem was. It's the same reason why I couldn't find help in google. – alexb Oct 31 '17 at 12:17