This may be slightly offtopic but too much sugar really makes things hard for beginners in Crystal.
Take for instance this:
class X
@service_files : {} of String => String
> expecting token 'CONST', not '}'
Well, looks correct no? I define the variable as a hash, with String key and String value. Wrong … did not work.
Hmmmm, maybe you need a specific different type.
class X
@service_files : Hash( String => String )
> instance variable '@service_files' of Shared::Service was not initialized directly in all of the 'initialize' methods, rendering it nilable. Indirect initialization is not supported.
No … more errors. And you keep going down the list of possibilities until you get fed up and write your code to simply auto initialize like this and are left with a bad taste because it just does not feel the correct way of doing it ( especially when you come from different language ).
class X
def initialize
@service_files = {} of String => String
end
> Yay, works ... but it feels like a hack rather then the correct way.
It was only until two days ago, when i noticed a piece of code on Gitter, where somebody finally used the ( in my eyes ) correct way of doing it.
class X
@service_files : Hash(String, String) = {} of String => String
This is frankly way too long and is undocumented. Searched for days trying to find a answer how to properly write this and there was no documented example available.
Good luck on figuring out that this is the way to write this because when you have Hash, {} of, and other ways of writing, it becomes very fast confusing. And yes, i had the answer in my hands all the time but your trying so many different combinations to figure out what, how, why???
I expect to see something
class X
@service_files : Hash(String, String) = {} of String => String
to work like
class X
@service_files : {} of String => String
@service_files : {"a" => 0} of String => String
Trust me when i say that Crystal at times really confuses me as a beginner. PHP has a bunch of gotcha’s but Crystal really makes things confusing.
Well, this also works:
class X
@service_files = {} of String => String
Slaps hand on head.
So you try:
class X
@service_files = Hash( String, String )
> But that does not work
They look the same in my eyes but they are not. And the documentation is very, very unclear in this regards, making it impossible to learn by example.
I have no problem figuring out { } of = Hash and [] of = Array but the initialization on a class level was annoying.
PS: Personally i noticed mostly the {} / [] of syntax as in my head {} = Hash, [] = Array. As a web developer your used to this pattern more with stuff like Jsons. The syntax is more clean to write.
{"a" => 0} of String => Int32
Hash(String, Int32){"a" => 0}
I dislike the “Hash” version because its less clean to read. Most of my code uses the “of” syntax.
The fact that {“a” => 0} of String => Int32 requires parentheses in specific situations looks more like a issue with the Crystal compiler. And yes, it confuses new users also. It needs to be a compiler check or the compiler needs to accept the syntax without the parentheses.