patternMinor
Multi-process FizzBuzz in Elixir
Viewed 0 times
elixirmultiprocessfizzbuzz
Problem
So I was playing with writing FizzBuzz in Elixir; this is my first, naive implementation:
So then I thought to myself--this is Elixir! I should be able to spawn a secondary process for my FizzBuzz needs. So after a bit of hacking I got this:
and I would use it like so:
I realize this is a small/simple example but I'd still love to hear the thoughts of other experienced Elixir devs. Where can I make this better?
defmodule FizzBuzz do
def getFB(n) do
cond do
rem(n,15) == 0 ->
IO.puts "FizzBuzz"
rem(n,3) == 0 ->
IO.puts "Fizz"
rem(n,5) == 0 ->
IO.puts "Buzz"
true ->
IO.puts "#{n}"
end
end
endSo then I thought to myself--this is Elixir! I should be able to spawn a secondary process for my FizzBuzz needs. So after a bit of hacking I got this:
defmodule FizzBuzz do
@fizz_buzz 15
@fizz 3
@buzz 5
@default_timeout 60_000
def getFB() do
receive do
{pid,n} when rem(n,@fizz_buzz) == 0 ->
send pid,"FizzBuzz"
{pid,n} when rem(n,@fizz) == 0 ->
send pid,"Fizz"
{pid,n} when rem(n,@buzz) == 0 ->
send pid,"Buzz"
{pid,n} ->
send pid,"#{n}"
after
@default_timeout -> raise "Timed out"
end
getFB() #Keep the process alive
end
endand I would use it like so:
fbPid = spawn &FizzBuzz.getFB/0
send fbPid,{self(),15}
receive do
r -> IO.puts(r)
after
1000 -> raise "Timed out"
endI realize this is a small/simple example but I'd still love to hear the thoughts of other experienced Elixir devs. Where can I make this better?
Solution
The use-case you came up with looks like a very clear candidate to be a
A
Here is a sample implementation of a fizzbuzz:
Its usage would be:
GenServer.A
GenServer implementation will eliminate your need to manage the serving process, and using its client-side API conventions will also simplify the client usage.Here is a sample implementation of a fizzbuzz:
defmodule FizzBuzz do
use GenServer
@fizz_buzz 15
@fizz 3
@buzz 5
def start_link(default) do
GenServer.start_link(__MODULE__, default, name: __MODULE__)
end
# Client API
def getFB(n) do
GenServer.call(__MODULE__, {:fb, n})
end
# Server API
def handle_call({:fb, n}, _from, state) when rem(n, @fizz_buzz) == 0 do
{:reply, "FizzBuzz", state}
end
def handle_call({:fb, n}, _from, state) when rem(n, @fizz) == 0 do
{:reply, "Fizz", state}
end
def handle_call({:fb, n}, _from, state) when rem(n, @buzz) == 0 do
{:reply, "Buzz", state}
end
def handle_call({:fb, n}, _from, state) do
{:reply, "#{n}", state}
end
endIts usage would be:
FizzBuzz.start_link([])
IO.puts FizzBuzz.getFB(15)
# FizzBuzzCode Snippets
defmodule FizzBuzz do
use GenServer
@fizz_buzz 15
@fizz 3
@buzz 5
def start_link(default) do
GenServer.start_link(__MODULE__, default, name: __MODULE__)
end
# Client API
def getFB(n) do
GenServer.call(__MODULE__, {:fb, n})
end
# Server API
def handle_call({:fb, n}, _from, state) when rem(n, @fizz_buzz) == 0 do
{:reply, "FizzBuzz", state}
end
def handle_call({:fb, n}, _from, state) when rem(n, @fizz) == 0 do
{:reply, "Fizz", state}
end
def handle_call({:fb, n}, _from, state) when rem(n, @buzz) == 0 do
{:reply, "Buzz", state}
end
def handle_call({:fb, n}, _from, state) do
{:reply, "#{n}", state}
end
endFizzBuzz.start_link([])
IO.puts FizzBuzz.getFB(15)
# FizzBuzzContext
StackExchange Code Review Q#57034, answer score: 9
Revisions (0)
No revisions yet.