Search code examples
objectprocesselixirspawn

Elixir program, what does this program do?


this is one of the practice questions from the upcoming exam, and I have no idea what should be written for init() in order for the output to run. If someone could help me out, that would be awsome

output: This is what I would run

p1=Pawn.new(),
Obj.call(p1,{:goto, 1, 2}),
1=Obj.call(p1, :x),
2=Obj.call(p1, :y),
Obj.call(p1,{:moveDelta , 3, 1}),
4=Obj.call(p1, :x ) ,
3=Obj.call(p1 ,:y ).  

Add the necessary code to the following to support the API used above for the object pawn:

function: I need to fill out the init() function here.

defmodule Obj do

def call(obj,msg) do
send obj,{self(), msg}

receive do
Response -> Response
end
   end
      end

defmodule Pawn do
def new(), do: spawn(__MODULE__,:init, [] ).
def init() do: // fill this out

Thank you for your time


Solution

  • I'm reluctant to do all your homework for you. However, given that the code you were given is not valid Elixir, I'll provide you a partial solution. I've implemented the :goto and :x handlers. You should be able to figure out how to write the :moveDelta and :y handlers.

    defmodule Obj do
      def call(obj, msg) do
        send obj, { self(), msg }
    
        receive do
          response -> response
        end
      end
    end
    
    defmodule Pawn do
      def new(), do: spawn(__MODULE__,:init, [] )
      def init(), do: loop({0,0})
      def loop({x, y} = state) do
        receive do
          {pid, {:goto, new_x, new_y}} -> 
            send pid, {new_x, new_y}
            {new_x, new_y}
          {pid, {:moveDelta, dx, dy}} -> 
            state = {x + dx, y + dy}
            send pid, state
            state
          {pid, :x} -> 
            send pid, x
            state
          {pid, :y} -> 
            send pid, y
            state
        end
        |> loop
      end
    end
    
    p1=Pawn.new()
    Obj.call(p1,{:goto, 1, 2})
    1=Obj.call(p1, :x)
    2=Obj.call(p1, :y)
    Obj.call(p1,{:moveDelta , 3, 1})
    4=Obj.call(p1, :x ) 
    3=Obj.call(p1 ,:y ) 
    

    The code runs. Here is the output of the test cases you provided (after I fixed the syntax issues:

    iex(5)> p1=Pawn.new()
    #PID<0.350.0>
    iex(6)> Obj.call(p1,{:goto, 1, 2})
    {1, 2}
    iex(7)> 1=Obj.call(p1, :x)
    1
    iex(8)> 2=Obj.call(p1, :y)
    2
    iex(9)> Obj.call(p1,{:moveDelta , 3, 1})
    {4, 3}
    iex(10)> 4=Obj.call(p1, :x )
    4
    iex(11)> 3=Obj.call(p1 ,:y )
    3
    iex(12)>
    

    Also, I fixed syntax issues in the given problem.