Estoy tratando de decodificar una respuesta websocket. Si contiene la clave 'símbolo', me gustaría imprimirlo.

He hecho esto:

msg                                                                                                                                   
|>Poison.decode!                                                                                                                      
|>Enum.member?("symbol")                                                                                                              
|>if                                             
|>IO.inspect

Como era de esperar, no le gustó mi 'si'. ¿Hay alguna forma de lograr esto?

0
cjm2671 26 oct. 2017 a las 21:19

3 respuestas

La mejor respuesta

Lamentablemente no puedes hacerlo, porque You can't pipeline into macros! Para lograr lo que necesita, simplemente coloque esto if en la función adecuada. O incluso mejor: ¡realiza la ramificación condicional utilizando diferentes cabezas de las funciones gracias a la coincidencia de patrones!

Enum.member/2 devolverá verdadero o falso, por lo que todo lo que necesita es:

defp processing_the_response(true) do
  # something
end

defp processing_the_response(false) do
  # something ELSE
end
3
PatNowak 26 oct. 2017 a las 18:30

Kernel.if/2 se define con una aridad de 2. En su tubería lo llamas con un arity de 1. Esto significa que no hay coincidencia para Kernel.if/1.

Además, su if debe devolver algo para que IO.inspect lo inspeccione

[true, false] 
|> Enum.random() 
|> if(do: 42, else: "You can't handle the truth") 
|> IO.inspect

O tal vez

[true, false]
|> Enum.random()
|> if do
        42
      else
        "You can't handle the truth"
      end
|> IO.inspect

O si desea devolver el resultado de la expresión en sí

["My random data", nil] 
|> Enum.random() 
|> (fn item -> if(item, do: item, else: "Sorry... no data!") end).() 
|> IO.inspect

O mejor

value
|> something(42)
|> something_else()
|> case do
     page where limit_size == nil -> page
     page -> page |> limit(size)
   end
|> some_more_things()

El último ejemplo está tomado de foro de elixir

Si desea que su enumerable pase por la tubería y obtenga una impresión ocasional, si hay una clave específica, aquí hay un enfoque

[a: 1, b: 3, c: 15]
|> (fn enumerable -> if(a = Access.get(enumerable, :a), do: IO.inspect(a, label: "The :a")); enumerable end ).()
|> (fn enumerable -> if(f = Access.get(enumerable, :f), do: IO.inspect(f, label: "This shouldn't be printed")); enumerable end ).()
|> IO.inspect(label: "The enumerable")

Aún así, la mejor manera es usar funciones con múltiples cabezas.

1
voger 27 oct. 2017 a las 18:52

¿Su respuesta es realmente una Lista o un Mapa? Porque Enum.member? no funcionará en un mapa. Si se trata de un mapa, puede aprovechar el patrón especial que hace que el elixir coincida con los mapas para lograr esto de una manera mucho más fácil

def show_result(%{"symbol" => _value} = msg) do 
  IO.inspect(msg) 
end 

def show_result(msg) do 
   msg
end 

Resultados en este código:

msg                                                                                                                                   
|> Poison.decode!                                                                                                                      
|> show_result
0
Fred the Magic Wonder Dog 26 oct. 2017 a las 20:16