michalmuskala / jason

A blazing fast JSON parser and generator in pure Elixir.
Other
1.6k stars 170 forks source link

Support ~j and ~J sigils. #121

Closed azizk closed 3 years ago

azizk commented 3 years ago

Hi!

I added a Sigil module because I thought it would be nice to have JSON sigils similar to ~y in YamlElixir.

azizk commented 3 years ago

Do you think the module name Sigil is fine? Or should it be Sigils?

michalmuskala commented 3 years ago

I think either one is fine. Given the name in the other library is Sigil, let's use the same.

michalmuskala commented 3 years ago

Thank you! :heart:

michalmuskala commented 3 years ago

I pushed a commit https://github.com/michalmuskala/jason/commit/468e1116a902ac98ad23bed80e7fed53553280237 that converts the sigils to macros to decode the strings at compile-time when possible

azizk commented 3 years ago

Thanks for being so responsive and merging! :heart:

One thing I noticed is you added a sentence to the doc of sigil_j: "Given a string literal without interpolations, decodes the string at compile-time." I think even with interpolations Elixir evaluates the decoding at compile-time. You don't even need macros for that. E.g.:

  x = &Jason.decode/2
  @y &Jason.decode!/2
  ~j'"#{inspect(x)}; #{inspect(@y)}"' |> IO.inspect(label: "~j with interpolations")

Or does it not happen in older Elixir versions without macros? Maybe I'm misunderstanding something... :)

michalmuskala commented 3 years ago

If you define the sigil as def it always happens at runtime. Only macros are expanded at compile-time. With def sigil_j this would be exactly the same as calling Jason.decode!("\"#{inspect(x)}; #{inspect(@y)}\"") except for the escapes & shorter syntax. With defmacro, it will be the same as writing a literal string.