PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0
Showing posts with label elixir. Show all posts
Showing posts with label elixir. Show all posts

Sunday, October 30, 2022

[FIXED] How to quit after run IO.read(:stdio, :all) in the Elixir iex?

 October 30, 2022     elixir, elixir-iex, eof, io     No comments   

Issue

I need test some input data flow, and use 'IO.read', but after entering data i can't exit from this mode, CTRL-Z/X/C/D doesn't help (it terminates the whole iex). So how correct EOF command for this mode? Thanks!


Solution

TL;DR: Use ^G followed by j, i [nn] and c [nn].


In both erl and iex shells you always might ^G to enter a “User switch command” mode. Type h for help there.

iex|1 ▶ IO.read :stdio, :all

^G
User switch command
  --> j
    1* {erlang,apply,[#Fun<Elixir.IEx.CLI.1.96155272>,[]]}
  --> i 1
  --> c 1
{:error, :interrupted}

iex|2 ▶

Sidenote: the correct EOF termination would be ^D in all the terminals. I honestly have no idea why it does not work as expected in erl/iex consoles.



Answered By - Aleksei Matiushkin
Answer Checked By - Willingham (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Monday, September 19, 2022

[FIXED] How to test the Elixir GenStage Consumer?

 September 19, 2022     consumer, elixir, ex-unit, genstage, producer-consumer     No comments   

Issue

I found some resources on how to test the producer, however there is nothing I could find which shows how to test the Consumer.

In producer, I create a dummy consumer and everything works fine, however in consumer I am struggling with testing.

defmodule DataProducer do
      use GenStage

      def start_link([]) do
        GenStage.start_link(__MODULE__, 0, name: __MODULE__)
      end

      # {:queue.new, demand, size}
      def init(counter) do
        {:producer, counter, dispatcher: GenStage.BroadcastDispatcher}
      end

      def handle_demand(demand, state) do 
        events = Enum.to_list(state..state + demand + 1)
        # Logger.info "demand is: #{inspect(demand)}, state is #{inspect(state)}"
        {:noreply, events, (state + demand)}
      end
    end

Producer Test:

 defmodule DataProducerTest do
      use ExUnit.Case

      test "check the results" do
        {:ok, stage} = DataProducer.start_link([])
        {:ok, _cons} = TestConsumer.start_link(stage)
        assert_receive {:received, events}
        GenStage.stop(stage)
      end

    end

    defmodule TestConsumer do
      def start_link(producer) do
        GenStage.start_link(__MODULE__, {producer, self()})
      end
      def init({producer, owner}) do
        {:consumer, owner, subscribe_to: [producer]}
      end
      def handle_events(events, _from, owner) do
        send(owner, {:received, events})
        {:noreply, [], owner}
      end
    end

And consumer:

defmodule DataConsumer do
  use GenStage
  def start_link([]) do
    GenStage.start_link(__MODULE__, :any_state)
  end
  def init(state) do
    {:consumer, state, subscribe_to: [{DataProducer, selector: fn n -> n > 50 && n < 100 end, max_demand: 10}]}
  end
  def handle_events(events, _from, state) do
    for event <- events do
      # :timer.sleep(250)
      Logger.info inspect( {self(), event, state} )
    end
    {:noreply, [], state}
  end
end

Thank you in advanced.


Solution

In the test for the consumer:

 test "should behave like consumer" do
    {:ok, producer} = DummyProducer.start_link(1)
    {:ok, consumer} = Consumer.start_link(producer)
    Process.register self, :test
    assert_receive {:called_back, 10}
  end

Now DummyProducer

defmodule DummyProducer do
  use GenStage

  def start_link(demand) do
    GenStage.start_link(__MODULE__, demand)
  end

  def init(demand) do
    {:producer, demand}
  end

  def handle_demand(demand, counter) when demand > 0 do
    events = Enum.to_list(counter..counter+demand-1)
    Process.send_after(self(), {:stop, demand}, 1)
    {:noreply, events, demand + counter}
  end

  def handle_info({:stop, demand}, state) do
    send :test, {:called_back, demand}
    {:stop, :normal, demand}
  end
end

I think,

The point of Testing the consumer is checking if consumer can send the demand and stick with max demand allocated in the subscription.



Answered By - Mr H
Answer Checked By - Mildred Charles (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Sunday, September 11, 2022

[FIXED] How Can I Find Default User Directories in Elixir

 September 11, 2022     cross-platform, elixir     No comments   

Issue

In many programming languages, there is a library call (part of the base packages or an external module) to locate the user's home directory, the documents directory, the configuration directory, and so forth, that isn't platform-specific. As an example of one that I've used recently for another language, Rust has "dirs." Is there an Elixir equivalent?

For example, I run a server on my local machine to handle some tasks, and recently wrote a client for it---a simple console application that sends a TCP request and gets a response---in Elixir. I would like to pull the port number from the existing configuration file, if the file exists, so that the value isn't hard-coded. I could do something like this, of course.

Path.join(System.user_home!(), ".config")

I guess System.user_home() is a start, itself, but not really sufficient. It'll fail miserably on a Windows machine, for example.

Searching the web turned up examples in plenty of non-Elixir languages, ways to search the current directory for a file in Elixir, and how to get the most out of the config directory in a Phoenix project, but nothing that I could see for just getting the configuration (or a similar) directory.

So, assuming that this has been done before (and I have to assume it has been, given how established Elixir has become), what's the current method for retrieving the user's configuration folder?


Solution

Not fully Elixir, but there is Erlang functions for that - filename:basedir/{2,3}

This function take the type of the directory as a first argument, which is one of the following atoms:

  • user_cache
  • user_config
  • user_data
  • user_log
  • site_config
  • site_data

And application name (also as atom) as a second argument.

Third argument may be a map containing:

  • os - OS type used for the paths creation, there are 3 recognisable values - windows, darwin (macOS), and linux (which will use XDG Base Directory Spec). Any other value will be treated as linux. If not provided, then OS is automatically detected by os:type/0 call.
  • author - used only on Windows
  • version - used only on Windows


Answered By - Hauleth
Answer Checked By - Pedro (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

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)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Wednesday, July 20, 2022

[FIXED] How to convert a binary to a base10 (decimal) integer in elixir

 July 20, 2022     base, elixir, encoding, erlang, int     No comments   

Issue

I would like to be able to convert an elixir string(binary) to a base10 integer.

I have been able to do this with the following...

<<104, 101, 108, 108, 111>> # equal to string "hello"
|> Base.encode16()
|> Integer.parse(16)

{448378203247, ""}

The above does what I am after but, feels a little like a hack. I would like to...

  • better understand what exactly is happening here
  • know if/how I would be able to do this in one step

Solution

Since Elixir strings are just binaries, you could probably use the erlang :binary.decode_unsigned function to convert binary digits to integers

From the documentation http://erlang.org/doc/man/binary.html#decode_unsigned-1

iex> :binary.decode_unsigned("hello")
448378203247

iex> :binary.encode_unsigned(448378203247)
"hello"

Essentially, the ascii values of hello is

<<104, 101, 108, 108, 111>>

when converted from decimal to hex can be written as

<<68, 65, 6C, 6C, 6F>>

or in binary as

<01101000, 01100101, 01101100, 01101100, 01101111>

which is a series of bytes stored as

68656C6C6F in hex or

01101000_01100101_01101100_01101100_01101111 in binary

whose decimal(base-10) value would be 448378203247

iex> Integer.to_string(448378203247, 16)
"68656C6C6F"

iex> Integer.to_string(448378203247, 2)
"110100001100101011011000110110001101111"
# each byte separated by _ is
# "1101000_01100101_01101100_01101100_01101111"
# missing a leading zero at the left, which doesn't change the value

edit: added binary example,

also, two hex digits can be used to perfectly denote a byte(4 bits needed to encode 16 values, 0 to 15) which is why when we denote in hex, we can just concatenate the hex values and not when they are in decimal(base-10) notation

From The wiki for hexadecimal

Hexadecimal numerals are widely used by computer system designers and programmers, as they provide a more human-friendly representation of binary-coded values. Each hexadecimal digit represents four binary digits, also known as a nibble, which is half a byte. For example, a single byte can have values ranging from 0000 0000 to 1111 1111 in binary form, which can be more conveniently represented as 00 to FF in hexadecimal.



Answered By - S.B
Answer Checked By - Mildred Charles (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Wednesday, May 18, 2022

[FIXED] How to read a portion of a file in Elixir (or Erlang)?

 May 18, 2022     elixir, erlang, file, partial     No comments   

Issue

How can we read only a selected portion of a file?

Like this: Read(file, start, length)


Solution

You can use :file.position/2 and :file.read/2.

With:

$ seq 10 > 10.txt

and code:

{:ok, file} = :file.open("10.txt", [:read, :binary])
:file.position(file, 5)
IO.inspect :file.read(file, 10)

The output is:

{:ok, "\n4\n5\n6\n7\n8"}

That's 10 bytes starting at the 6th byte.



Answered By - Dogbert
Answer Checked By - Senaida (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Saturday, May 14, 2022

[FIXED] How to debug Elixir with erlangs GUI debugger on Ubuntu-based linux?

 May 14, 2022     debugging, elixir, erlang, ubuntu, wxwidgets     No comments   

Issue

I installed Erlang and Elixir as recommended in the Elixir documentation for Ubuntu & Debian.

The results of running elixir -v:

Erlang/OTP 24 [erts-12.2.1] [source] [64-bit] [smp:32:32] [ds:32:32:10] [async-threads:1] [jit]

Elixir 1.13.0 (compiled with Erlang/OTP 24)

When I enter iex and try to start the debugger GUI with :debugger.start(), I get the following error:

12:22:51.248 [error] WX ERROR: Could not load library: :load_failed
Failed to load NIF library /usr/lib/erlang/lib/wx-2.1.1/priv/wxe_driver: 'libwx_gtk3u_webview-3.0.so.0: cannot open shared object file: No such file or directory'
{:error,
 {{:error,
   {:load_failed,
    'Failed to load NIF library /usr/lib/erlang/lib/wx-2.1.1/priv/wxe_driver: \'libwx_gtk3u_webview-3.0.so.0: cannot open shared object file: No such file or directory\''}},
  [
    {:wxe_server, :start, 1, [file: 'wxe_server.erl', line: 65]},
    {:wx, :new, 1, [file: 'wx.erl', line: 115]},
    {:dbg_wx_win, :init, 0, [file: 'dbg_wx_win.erl', line: 46]},
    {:dbg_wx_mon, :init, 3, [file: 'dbg_wx_mon.erl', line: 114]}
  ]}}

I checked the path /usr/lib/erlang/lib/wx-2.1.1/priv/ and found wxe_driver.so there.


Solution

I found that the missing object file that was referenced, libwx_gtk3u_webview-3.0.so.0, is included in this package's filelist.

I installed the package with

sudo apt install libwxgtk-webview3.0-gtk3-0v5

and now :debugger.start() and :observer.start() launch their respective GUIs.

I answered my own question in the hopes that it'll help others and my future self. Anyone with further insight into why this package was missing from my installation and is not referenced anywhere in the Erlang or Elixir installation documentation, please add an answer or comment. I'm wondering if I missed something during the initial installation because I haven't found other reports of this issue.



Answered By - orangecaterpillar
Answer Checked By - Willingham (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Thursday, April 28, 2022

[FIXED] How do we resolve conflicting behaviours warnings in Elixir

 April 28, 2022     behavior, elixir, warnings     No comments   

Issue

How may we resolve conflicting behaviours warnings in Elixir?

warning: conflicting behaviours found. function handle_info/2 is required by Raxx.Server and GenServer

For example, I need to use both GenServer and Raxx.SimpleServer in a modeule, and both define the @callback handle_info

defmodule TestServer
 use Raxx.SimpleServer
 use GenServer

 def handle_info(_, state), do: {:noreply, state}    
end

Please what's the best/recommended workaround for this?


Solution

TL;DR: you cannot suppress this warning because you are not supposed to cross-violate behaviours. OTOH, it’s just a convention and the code would probably happily run despite the warning.


This is surely an XY Problem. In the first place, you should explicitly tell the compiler that handle_info/2 is an implementation:

@impl GenServer # or @impl true
def handle_info(_, state), do: {:noreply, state} 

Secondarily, the design as stated, even if it was welcome and did not produce any warning, violates SRP.

What you probably should do, is a supervision tree with a supervisor, managing two workers: one for Raxx.SimpleServer, and another one for GenServer. When the interoperation is required, you should pass the message to the respective process.



Answered By - Aleksei Matiushkin
Answer Checked By - Marie Seifert (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Older Posts Home

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
All Comments
Atom
All Comments

Copyright © PHPFixing