1

This is the correct answer below, but I'm not understanding why it is ok to type "puts word" in the last line, whereas it's not acceptable to type "puts x" since it is defined in almost the exact same way

puts "Text please "
text = gets.chomp

words = text.split(" ")
frequencies = Hash.new{0}

words.each { |word| frequencies[word] += 1}

frequencies = frequencies.sort_by { |x, y| y }
frequencies.reverse!
frequencies.each do |word, frequency|
    puts word + " " + frequency.to_s
end
Michael Berkowski
  • 267,341
  • 46
  • 444
  • 390
rhn
  • 21
  • 2
  • 1
    As a tip, when entering a code block you may highlight the whole thing and Ctrl-k to format it as a code block. Or highlight and click the `{}` button in the edit toolbar. – Michael Berkowski Nov 12 '13 at 18:57
  • possible duplicate of [How to iterate over a hash in Ruby?](http://stackoverflow.com/questions/1227571/how-to-iterate-over-a-hash-in-ruby) – Ura Nov 12 '13 at 19:00
  • 1
    Not a duplicate of that question - this is actually about variable scope. – joews Nov 12 '13 at 19:00

3 Answers3

2

It's defined in the same way, as a code block parameter, but not the same place. Code blocks can use variables provided as parameters or defined inside themselves, so puts word is OK, or in the parent scope (the code which created the block - the "top level" in this case), so puts frequencies would also be ok.

However, x comes from a completely different code block so the block at the bottom doesn't know about it. x only has meaning within the block that you pass to frequencies.sort_by.

undur_gongor
  • 15,657
  • 5
  • 63
  • 75
joews
  • 29,767
  • 10
  • 79
  • 91
  • Ah, I see. So if the third to last line said `do |x, frequency|`, `puts x` would be acceptable? – rhn Nov 12 '13 at 19:05
0

It's not defined in the same way.

x is defined in the sort_by block of frequencies.

It's not defined there.

It would work if you had put instead:

frequencies.each do |x, y|
    puts x + " " + y.to_s
end

for example, but x and y aren't defined outside of {}, or in this case, do...end

Plasmarob
  • 1,321
  • 12
  • 20
  • So it is alright to say "puts word" because it is a placeholder in the .each block? – rhn Nov 12 '13 at 19:01
0

I think you are confused on the scope of your placeholders. On the last line you use |word,frequency| as your placeholders in frequencies.each do |word, frequency|, whereas your |x,y| is scoped to your first each in frequencies = frequencies.sort_by { |x, y| y }

As an aside, perhaps it would be best if you renamed your |x, y| to something specific? You can get lost in code if you don't properly define your variables, methods, placeholders etc. Just a thought.

Matt16749
  • 119
  • 11