angelikatyborska

angelikatyborska

I’m having trouble understanding why function deprecation warnings don’t always show up when I compile code that uses deprecated functions.

Let me explain with an example: HashDict.new/0 is a deprecated function. Let’s say I have a file called deprecated_test.ex. The file contains a module and a function definition that uses the deprecated function:

# deprecated_test.ex
defmodule Foo do
  def foo, do: HashDict.new()
end

If I compile the file with elixirc, I get a nice deprecation warning:

angelika in ~/Documents
$ elixirc deprecated_test.ex
warning: HashDict.new/0 is deprecated. Use maps and the Map module instead
  deprecated_test.ex:2: Foo.foo/0

However, if I start iex, load the same file and compile it with Code.compile_string/1, I don’t get the warning:

iex(2)> code = File.read!("./deprecated_test.ex")
"defmodule Foo do\n  def foo, do: HashDict.new()\nend\n"

iex(3)> Code.compile_string(code)
[
  {Foo,
   <<70, 79, 82, 49, 0, 0, 4, 208, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 0,
     153, 0, 0, 0, 16, 10, 69, 108, 105, 120, 105, 114, 46, 70, 111, 111, 8, 95,
     95, 105, 110, 102, 111, 95, 95, 10, 97, 116, ...>>}
]

I thought this means that Code.compile_string/1 won’t give me deprecation warnings at all, but that’s not true.

I get a deprecation warning about HashDict.new/0 if I try different code snippets:

iex(4)> Code.compile_string("fn -> HashDict.new() end")
warning: HashDict.new/0 is deprecated. Use maps and the Map module instead
  nofile:1

[]

or

iex(15)> Code.compile_string("ref = &HashDict.new/0")
warning: HashDict.new/0 is deprecated. Use maps and the Map module instead
  nofile:1

warning: variable "ref" is unused (if the variable is not meant to be used, prefix it with an underscore)
  nofile:1

[]

Why is this happening? Can I somehow ensure that I will always get exactly the same deprecation warnings when compiling code with Code.compile_string/1 and/or Code.compile_quoted/1 as I would get with elixirc?

Showing Posts 1 to 4

moogle19

moogle19

It seems that compile_file/2 call the private function verify_loaded/1 in Code which verifies some things (e.g. deprecations) (see code.ex#L1503).
compile_string/2 doens’t (see code.ex#L1466).

Not sure why only the compile_file/2 checks this. Maybe performance reasons?

angelikatyborska

angelikatyborska OP

Thanks a lot! Based on your hints, I was able to get the deprecation checks working fully.

The only purpose of my code is to get all the compilation warnings. Here’s what I had before:

warnings =
  capture_io(:stderr, fn ->
    Code.compile_quoted(code_ast, Path.basename(code_path))
    |> Enum.each(fn {module, _binary} ->
      :code.delete(module)
      :code.purge(module)
    end)
  end)

And here’s what I have now:

warnings =
  capture_io(:stderr, fn ->
    :elixir_compiler.quoted(code_ast, code_path, fn _, _ -> :ok end)
    |> Enum.each(fn {module, map, binary} ->
      Module.ParallelChecker.verify([{map, binary}], [])
      :code.delete(module)
      :code.purge(module)
    end)
  end)

I’m just not sure if it’s a great idea to use a private module (Module.ParallelChecker) like this.

josevalim

josevalim

Creator of Elixir

Both :elixir_compiler and Module.ParallelChecker are private, so please don’t use them. :slight_smile: Please open up an issue and we will make sure to also check for deprecations from compile_string. :slight_smile:

angelikatyborska

angelikatyborska OP

That would be great :purple_heart: I opened the issue on GitHub.

— All posts loaded —

Where Next? Top

Trending in Questions Top

stjefim
Hello! Suppose you are building workflow (order / task / payment) processing system with the following requirements: Each workflow con...
New
water
I’m aware of 2 such projects, are there others? git: GitHub - team-alembic/realworld: A fullstack Phoenix LiveView application with back...
New
katta
I having some trouble figuring out if I have set myself too strict of standards for my production server. Currently I can handle 75% of r...
New
peck
Hi everyone. My team and I have been working on a fairly modest app based around video streaming and chat, but we’ve landed a customer t...
New
bradley
I really like the adapter patterns that ecto, nebulex, waffle, etc. use and would love find something similar for a key management servic...
New
unaware8150
Hello folks! So at work, we are seeing some situations where we have to define some “fixed” strings that are used across the codebase in...
New
Alvinkariuki
How Can I Optimise Compile Time Dependencies I have been building an elixir application for about 2 years now. Many modules and files ha...
New

Other Trending Topics Top

KristerV
Hey. Is there anyone here who creates agents in their apps? Not talking about using agents, but creating them. I’m finding it pretty diff...
New
mudasobwa
I fully migrated to my own harness from Anthropic/Gemini and I think it’s time to share it. Welcome DSH, the DeepSeek Harness, fully writ...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
juhalehtonen
There has been a thread to discuss the Stack Overflow Developer Survey on this forum every year since 2018, so here’s yet another one for...
New
budgie
I love Elixir. It’s one of 2 programming languages I’ve ever fallen in love with. But I don’t use it anymore. Serverless was the promis...
New
ausimian
Emily is an Elixir library that runs Nx computations on Apple’s MLX. Install it as the default Nx backend and Nx, defn, Axon, Nx.Serving,...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews