Why does String#% method not work with hash having keys as strings?

I am good with the below two :

hash = {"_id"=> 12, “result”=>2177, “time” => ‘2014-05-22 06:15:45 UTC’
}
“%s => %s” % hash.values_at(‘time’, ‘result’)

=> “2014-05-22 06:15:45 UTC => 2177”

!> too many arguments for format string

hash = {"_id"=> 12, :result => 2177, :time => ‘2014-05-22 06:15:45 UTC’
}
“%{time} => %{result}” % hash # !> possibly useless use of % in void
context

=> “2014-05-22 06:15:45 UTC => 2177”

the below is not working

hash = {"_id"=> 12, “result”=>2177, “time” => ‘2014-05-22 06:15:45 UTC’
}
“%{time} => %{result}” % hash

~> -:6:in `%’: key{time} not found (KeyError)

~> from -:6:in `’

Does it mean I can use String#% to hash only when Hash will have keys as
a
symbol ? Or there is a trick, that I am missing.

On Sat, May 31, 2014 at 2:12 AM, Arup R.
[email protected] wrote:

the below is not working

hash = {“_id”=> 12, “result”=>2177, “time” => ‘2014-05-22 06:15:45 UTC’ }
“%{time} => %{result}” % hash

~> -:6:in `%': key{time} not found (KeyError)

~> from -:6:in `’

Does it mean I can use String#% to hash only when Hash will have keys as a
symbol ? Or there is a trick, that I am missing.

no tricks here. just plain ruby code

“%{time} => %{result}” % hash.map{|k,v| [k.to_s.to_sym,v]}.to_h
=> “2014-05-22 06:15:45 UTC => 2177”

best regards
-botp

On Fri, May 30, 2014 at 8:12 PM, Arup R.
[email protected] wrote:

Does it mean I can use String#% to hash only when Hash will have keys as a
symbol ? Or there is a trick, that I am missing.

String#% does not hash - it’s a shortcut for sprintf():

irB(mAin):008:0> “A%04dB” % 1
=> “A0001B”
irB(mAin):009:0> “A%04dB” % 34
=> “A0034B”
irB(mAin):010:0> “A%04dB%pX” % [34, 99]
=> “A0034B99X”
irB(mAin):011:0> “A%04dB%pX” % [34, [1,2]]
=> “A0034B[1, 2]X”

irb(main):012:0> sprintf “A%04dB”, 1
=> “A0001B”
irb(main):013:0> sprintf “A%04dB”, 34
=> “A0034B”
irb(main):014:0> sprintf “A%04dB%pX”, 34, 99
=> “A0034B99X”
irb(main):015:0> sprintf “A%04dB%pX”, 34, [1,2]
=> “A0034B[1, 2]X”

Cheers

robert

On May 31, 2014, at 6:18, Robert K. [email protected]
wrote:

irB(mAin):009:0> “A%04dB” % 34
irb(main):014:0> sprintf “A%04dB%pX”, 34, 99
=> “A0034B99X”
irb(main):015:0> sprintf “A%04dB%pX”, 34, [1,2]
=> “A0034B[1, 2]X”

Not true anymore:

% ri String.%
= String.%

(from ruby core)

str % arg → new_str


Format—Uses str as a format specification, and returns the result of
applying it to arg. If the format specification contains more than one
substitution, then arg must be an Array or Hash containing the values to
be substituted. See Kernel::sprintf for details of the format string.

“%05d” % 123 #=> “00123”
“%-5s: %08x” % [ “ID”, self.object_id ] #=> “ID : 200e14d6”
“foo = %{foo}” % { :foo => ‘bar’ } #=> “foo = bar”

On Jun 2, 2014, at 0:27, Robert K. [email protected]
wrote:

String#% does not hash - it’s a shortcut for sprintf():
irb(main):012:0> sprintf “A%04dB”, 1
What is not true any more? You are just confirming what I wrote above.
I read your statement to say that String#% doesn’t handle hashes, tho on
second reading you might have meant that it doesn’t #hash. Not that I
can figure out why you’d say such a thing. Arup’s mail was pretty clear
that he was using String#% with a hash argument.

applying it to arg. If the format specification contains more than one
substitution, then arg must be an Array or Hash containing the values to
be substituted. See Kernel::sprintf for details of the format string.

“%05d” % 123 #=> “00123”
“%-5s: %08x” % [ “ID”, self.object_id ] #=> “ID : 200e14d6”
“foo = %{foo}” % { :foo => ‘bar’ } #=> “foo = bar”

Yes, exactly my point.

Not exactly your point. None of your examples of sprintf are like the
last example of the String#% rdoc:

“foo = %{foo}” % { :foo => ‘bar’ }

returns:

“foo = bar”

So you were confusing the issue when the OP was clearly using a hash
argument.

On Mon, Jun 2, 2014 at 12:20 PM, Ryan D. [email protected]
wrote:

On Jun 2, 2014, at 0:27, Robert K. [email protected] wrote:

On Mon, Jun 2, 2014 at 6:55 AM, Ryan D. [email protected] wrote:

Not true anymore:

What is not true any more? You are just confirming what I wrote above.

I read your statement to say that String#% doesn’t handle hashes, tho on second
reading you might have meant that it doesn’t #hash. Not that I can figure out why
you’d say such a thing. Arup’s mail was pretty clear that he was using String#%
with a hash argument.

Well, I read it differently but there you go.

Not exactly your point. None of your examples of sprintf are like the last
example of the String#% rdoc:

“foo = %{foo}” % { :foo => ‘bar’ }

returns:

“foo = bar”

So you were confusing the issue when the OP was clearly using a hash argument.

I was replying to the OP’s question “Does it mean I can use String#%
to hash?” You cannot use String#% to hash something - it’s just a
formatting function. I just did not provide examples for all use
cases.

Cheers

robert

On 2 June 2014 21:30, Robert K. [email protected] wrote:

I was replying to the OP’s question “Does it mean I can use String#%
to hash?” You cannot use String#% to hash something - it’s just a
formatting function. I just did not provide examples for all use
cases.

​I suspect Arup meant “with a hash” rather than "to hash."​ Only folk
with
a certain amount of computer science type background would consider “to
hash” to be a verb. Further, I’d imagine someone without that
background,
and maybe without the same fluency in English, would have misinterpreted
your “String#% does not hash” statement similarly (i.e. as “String#%
does
not accept a hash”), and thus confusion ensues.

Though it’d be kind of cool if String#% had a format thingy for the MD5
of
the input. :wink:

On Mon, Jun 2, 2014 at 6:55 AM, Ryan D. [email protected]
wrote:

=> “A0001B”
irb(main):013:0> sprintf “A%04dB”, 34
=> “A0034B”
irb(main):014:0> sprintf “A%04dB%pX”, 34, 99
=> “A0034B99X”
irb(main):015:0> sprintf “A%04dB%pX”, 34, [1,2]
=> “A0034B[1, 2]X”

Not true anymore:

What is not true any more? You are just confirming what I wrote above.

applying it to arg. If the format specification contains more than one
substitution, then arg must be an Array or Hash containing the values to
be substituted. See Kernel::sprintf for details of the format string.

“%05d” % 123 #=> “00123”
“%-5s: %08x” % [ “ID”, self.object_id ] #=> “ID : 200e14d6”
“foo = %{foo}” % { :foo => ‘bar’ } #=> “foo = bar”

Yes, exactly my point.

Cheers

robert

On Saturday, May 31, 2014 03:01:57 PM botp wrote:
no tricks here. just plain ruby code

“%{time} => %{result}” % hash.map{|k,v| [k.to_s.to_sym,v]}.to_h

=> “2014-05-22 06:15:45 UTC => 2177”

best regards
-botp

I wouldn’t convert a hash to hash again. Because for me, it is then easy
to
use array .

hash = {"_id"=> 12, “result”=>2177, “time” => ‘2014-05-22 06:15:45 UTC’
}
“%s => %s” % hash.values_at(‘time’, ‘result’)

=> “2014-05-22 06:15:45 UTC => 2177”

Regards,
Arup R.

Debugging is twice as hard as writing the code in the first place.
Therefore,
if you write the code as cleverly as possible, you are, by definition,
not
smart enough to debug it.

–Brian Kernighan

On Monday, June 02, 2014 01:30:51 PM Robert K. wrote:
So you were confusing the issue when the OP was clearly using a hash
argument.
I was replying to the OP’s question “Does it mean I can use String#%
to hash?” You cannot use String#% to hash something - it’s just a
formatting function. I just did not provide examples for all use
cases.

That’s my mistake and bad English made you guys confused.

My straight question was -

We can pass a hash object as an argument to the method String#%. But
when
the hash will be having keys as a string object, if i try to access it,
it
will throw error as below :

hash = { ‘apple’ => 2 }

“I want %{apple} apples” % hash
#key{apple} not found (KeyError)

But no problem, while the hash is having keys as symbols -

hash = { :apple => 2 }

“I want %{apple} apples” % hash

=> “I want 2 apples”

Why so? Because I didn’t find any such note in the documentation.

Regards,
Arup R.

Debugging is twice as hard as writing the code in the first place.
Therefore,
if you write the code as cleverly as possible, you are, by definition,
not
smart enough to debug it.

–Brian Kernighan