PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Wednesday, August 24, 2022

[FIXED] What is the difference between defdelegate and def with call module function directly in Elixir

 August 24, 2022     elixir, function, module     No comments   

Issue

I have module that is mostly used as a namespace. Let us call it Bla. There are other submodules, that have methods with specific functions to that submodule.

However, I want to have two options:

  1. import main module Bla and use all functions from submodules directly (not to write multiple imports separately)

  2. import only specific submodule like Bla.Subbla to use functions only from this module without importing functions from other submodules

This is what I have:

defmodule Bla do
  defdelegate bla_func(text), to: Bla.Subbla
  defdelegate bla_func(text, opts), to: Bla.Subbla
end
    
defmodule Bla do
  def bla_func(text), do: Bla.Subbla.bla_func(text)
  def bla_func(text, opts), do: Bla.Subbla.bla_func(text, opts)
end

What is the right way to do that? I have two options, but have no idea, maybe, there is much more better one. Are those two options equivalent? And which one is preferable? Is there any difference in performance?


Solution

A few differences I can think of:

  1. When you are using defdelegate your intent is very clear, you are just delegating the method to another method in another module. And that this is just a dumb forwarder.
  2. With defdelegate you cannot change the arguments, whether be it the order, addition or removal of arguments. So, if all you really want is to forward the method call use defdelgate as there is less scope to screw up.
  3. In some cases defdelegate is not an option as you need to add more data to the forwarding function, in which case you don't really have an option.

So, the bottomline is: if possible always use defdelegate, you will avoid a few classes of bugs using it. e.g. below:

defmodule Greet do
  def greet(name, greeting) do
    IO.puts "#{greeting} #{name}"
  end
end
    
defmodule DelegatedGreet do
  defdelegate greet(name, greeting), to: Greet
end
    
defmodule BuggyGreet do
  # scope for bugs like these
  def greet(name, greeting), do: Greet.greet(greeting, name)
end


Answered By - Khaja Minhajuddin
Answer Checked By - David Goodson (PHPFixing Volunteer)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing