Why Can't I Use an Integer as a Key Using the New Ruby 1.9.2 Hash Syntax

Why can't I use an integer as a key using the new Ruby 1.9.2 hash syntax?

This syntax is only for Ruby 'symbols', and is an alternative to the common usage:

:symbol => 5

rather than as a general key. More on symbols here. And others have written about this with respect to the principal of least surprise (see here).

Error while creating ruby 1.9 hash


day = {one: "Sunday", two: "Monday"}

is the new syntax comes from version 1.9, which is same as

day = {:one =>  "Sunday", :two => "Monday"}

Only the key is symbol you could use the that syntax.

You have to use day = {1 => "Sunday", 2 => "Monday"} in your case.

In the future, can I use the new hash syntax with array as key?


But I have been able to do the same with a string ...

I think you are referring to the "name": value syntax.

Let's see:

{"foo": 123} #=> {:foo=>123}

Notice what happens to the "string"? It becomes a symbol.

Within a hash literal "foo": value is a shortcut for :"foo" => value and :"foo" is in fact a symbol:

:"foo" #=> :foo

I would like to know if they will implement it in the future (just because syntactic sugar)?

Who knows? But I don't think so.

Using nested hash and a hash as default value isn't working as expected

It is because a[:a] is never assigned. When you do a[:a], it is not returning the stored value, but is returning the default value.

Unlike this, when you instead have:

a = Hash.new{|h, k| h[k] = {a: 1}}

then, whenever a missing key is called, the block is executed, which assigns the value to the key, and a will no longer be an empty hash.

Has #puts created a new hash?

You are passing a hash to puts. In ruby, if the last argument you're passing to a function is a hash the curly braces are optional. So your example is equivalent to:

puts( {:some_object => 'another_object'} )

Why is 300 .intern valid but :300 is not

The symbol you create by saying puts "300".to_sym isn't creating the symbol with a Fixnum, it's creating it with a string. You seem to be mixing up Fixnum's versus strings here.

:"300" is a valid symbol

:300 is not

When you type puts "300".to_sym, it returns :"300"

1.9.3-p484 :002 > "300".to_sym
=> :"300"

You could just as easily make your hash

1.9.3-p484 :013 > hsh = {
1.9.3-p484 :014 > :"300" => 3,
1.9.3-p484 :015 > :something_else => 2
1.9.3-p484 :016?> }
=> {:"300"=>3, :something_else=>2}
1.9.3-p484 :017 > hsh[:"300"]
=> 3

and that would work fine.

Your problem would be more accurately stated if you tried to send to_sym to a Fixnum.

1.9.3-p484 :018 > 300.to_sym
NoMethodError: undefined method `to_sym' for 300:Fixnum
from (irb):18
from /Users/rsahae/.rvm/rubies/ruby-1.9.3-p327/bin/irb:18:in `<main>'

Why does clearing my hash, also clear my array of hashes?

When you do a << h, you are really passing the reference of h to a. So when you update h, a also see's those changes because it contains a reference rather than a copy of that value.

In order for it not to change in a, you must pass a cloned value of h into a.

An example would be:

a << h.clone

Hash constructor parameter in 1.9.*

You don't need the splat (*) to capture a single hash argument. It's used to capture an unknown number of arguments. Change your function definition to

def initialize(params = {})
@attr1 = params[:attr1] or nil
@attr2 = params[:attr2] or nil
end

and everything should work the way you'd expect. Edit: The params = {} makes the params argument optional, and sets it to an empty hash when nothing is provided.

What's actually being captured in params with the function definion you have now, would be like this:

Whatever.new(:foo => 'foo', :bar => 'bar')
# params contains [{:foo => 'foo', :bar => 'bar'}]

so you'd need to reach into the array first to get the hash, then use the hash keys.

When Ruby sees a set of hash key/value pairs as the last argument to a function, it's automatically wrapped into a Hash. So even though it looks like you're supplying multiple arguments to the function, the interpreter is actually only receiving a single argument.

Internal Server Error can't convert String into Integer (in Rails)

I solved the error using the old version of project and using the db with above given migrations applied on it. Then i started entering the new code of model in my project, and ran the project, the error was gone!
Thanks



Related Topics



Leave a reply



Submit