과거 칼럼 ZEN Style화①:재귀로 쓰인 key에 의한 로직 전환(Strategy/State 패턴을 Elixir답게 스마트하게)
13435 단어 fukuoka.exElixir
방문해 주셔서 감사합니다
과거 Qiita Elixir 칼럼을 "Elixir ZEN Style"로 다시 작성하면 어떻게 될지의 미니 칼럼입니다.
이번에는, @다루이_부터 씨가 쓰여진 아래의 칼럼으로 해 보겠습니다
[Elixir] 키워드 목록의 키로 처리를 변경하는 예
htps : // 이 m/더러운_에서/있어 ms/364b75f1cd8d28df6272
덧붙여 「Elixir ZEN Style」에 대해서는, 아래의 칼럼을 봐 주세요
Elixir Zen 스타일 프로그래밍 강좌
htps : // 코 m / 쟈키 1972 / ms / 619f39 c77f b52b1 bf
이 칼럼의 검증 환경
본 칼럼은, 이하 환경에서 검증하고 있습니다(Windows에서 실시하고 있습니다만, Linux나 mac에서도 동작한다고 가정합니다)
키워드 목록의 키로 로직 전환
키워드 리스트의 key마다, 다른 처리를 실행할 수 있는 전환을, 등록이 끝난 key의 리스트와, 함수의 가드로 실현하고 있는 것이, 전 칼럼의 내용입니다
모듈의 "@ 변수"에 키 목록을 등록하고 가드 "in"에서 목록과 일치합니다.
defmodule ArgumentsSample do
@spec sample(Keyword.t) :: any
def sample(kw) do
keys = Keyword.keys(kw)
values = Keyword.values(kw)
IO.puts "Start..."
sample(keys, values)
end
@match1 [:hoge, :huge]
@match2 [:foo, :bar]
defp sample([key|keys_tail], [value|values_tail]) when key in @match1 do
IO.puts "@match1 match"
IO.puts "#{key} = #{value}"
sample(keys_tail, values_tail)
end
defp sample([key|keys_tail], [value|values_tail]) when key in @match2 do
IO.puts "@match2 match"
IO.puts "#{key} = #{value}"
sample(keys_tail, values_tail)
end
defp sample(key, value) do
IO.puts "...End"
end
end
실행 결과는 다음과 같습니다.
iex> ArgumentsSample.sample hoge: 1, foo: 2, bar: 3, hoge: 4, huge: 5
Start...
@match1 match
hoge = 1
@match2 match
foo = 2
@match2 match
bar = 3
@match1 match
hoge = 4
@match1 match
huge = 5
...End
:ok
원래 코드가 재귀로 구현되는 곳을 Enum.each에서 Elixir ZEN Style화합니다.
defmodule ArgumentsSample do
@spec sample( Keyword.t ) :: any
def sample( kw ) when is_list( kw ) do
IO.puts "Start..."
kw |> Enum.each( & sample( &1 ) )
IO.puts "...End"
end
@match1 [ :hoge, :huge ]
@match2 [ :foo, :bar ]
def sample( { key, value } ) when key in @match1 do
IO.puts "@match1 match"
IO.puts "#{ key } = #{ value }"
end
def sample( { key, value } ) when key in @match2 do
IO.puts "@match2 match"
IO.puts "#{ key } = #{ value }"
end
end
실행 결과는 변하지 않고 동일한 결과가 출력됩니다.
다시 쓰기 포인트
defmodule ArgumentsSample do
@spec sample(Keyword.t) :: any
def sample(kw) do
keys = Keyword.keys(kw)
values = Keyword.values(kw)
IO.puts "Start..."
sample(keys, values)
end
@match1 [:hoge, :huge]
@match2 [:foo, :bar]
defp sample([key|keys_tail], [value|values_tail]) when key in @match1 do
IO.puts "@match1 match"
IO.puts "#{key} = #{value}"
sample(keys_tail, values_tail)
end
defp sample([key|keys_tail], [value|values_tail]) when key in @match2 do
IO.puts "@match2 match"
IO.puts "#{key} = #{value}"
sample(keys_tail, values_tail)
end
defp sample(key, value) do
IO.puts "...End"
end
end
iex> ArgumentsSample.sample hoge: 1, foo: 2, bar: 3, hoge: 4, huge: 5
Start...
@match1 match
hoge = 1
@match2 match
foo = 2
@match2 match
bar = 3
@match1 match
hoge = 4
@match1 match
huge = 5
...End
:ok
defmodule ArgumentsSample do
@spec sample( Keyword.t ) :: any
def sample( kw ) when is_list( kw ) do
IO.puts "Start..."
kw |> Enum.each( & sample( &1 ) )
IO.puts "...End"
end
@match1 [ :hoge, :huge ]
@match2 [ :foo, :bar ]
def sample( { key, value } ) when key in @match1 do
IO.puts "@match1 match"
IO.puts "#{ key } = #{ value }"
end
def sample( { key, value } ) when key in @match2 do
IO.puts "@match2 match"
IO.puts "#{ key } = #{ value }"
end
end
효과
이 기법의 사용점
소위 「Strategy 패턴」이나 「State 패턴」과 같은, 입력이나 상태에 의해, 핸들러를 스위치 하는 것과 같은 것이면, 이 테크닉에 의해, 매우 보수성이 높고, 전망이 좋은 코드가 됩니다(일일이 클래스 을 만드는 우자함도 Elixir이므로 당연하지 않습니다)
키워드 리스트에 입력이나 상태를 늘어놓고, 핸들러를 부르는 key 마다 그룹핑을 실시하면 OK입니다
덧붙여 각 리스트에 key가 단수 밖에 없는 경우는, 아래와 같이, 함수 패턴 매치로서 직접 쓰면 좋기 때문에, in에 의한 가드도, 「@변수」의 등록도, 불필요하게 됩니다
…
def sample( { :hoge, value } ) do
IO.puts "@match1 match"
IO.puts "#{ key } = #{ value }"
end
def sample( { :foo, value } ) do
IO.puts "@match2 match"
IO.puts "#{ key } = #{ value }"
end
…
그건 그렇고 ...
가드의 "in"지정이 "@ 변수"가 아니면 오류가 발생합니다.
이것은 이상한 사양과 같이 보입니다만, 가드에 쓸 수 있는 구문에는, 비교적 제약이 있다(동적인 함수나 자기 정의 함수는 우선 사용할 수 없다) 때문에, 하는 방법은 없습니다
아마도 ``@variables''는 컴파일 타임에 상수이기 때문에이 제약에 걸리지 않을 것입니다.
p.s.「좋아요」 잘 부탁드립니다
페이지 왼쪽 상단의 또는 을 클릭해 주셔서 감사합니다
여기의 숫자가 늘어나면, 필자로서는 「우케하고 있다」라는 감각을 얻을 수 있어 연재를 더욱 진화시켜 나가는 동기 부여가 되기 때문에, 보다 Elixir 재료를 보고 싶다고 하는 당신, 저희와 함께 북돋워 제발!
Reference
이 문제에 관하여(과거 칼럼 ZEN Style화①:재귀로 쓰인 key에 의한 로직 전환(Strategy/State 패턴을 Elixir답게 스마트하게)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/piacerex/items/66c9e533f9701deeb7b4
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
…
def sample( { :hoge, value } ) do
IO.puts "@match1 match"
IO.puts "#{ key } = #{ value }"
end
def sample( { :foo, value } ) do
IO.puts "@match2 match"
IO.puts "#{ key } = #{ value }"
end
…
가드의 "in"지정이 "@ 변수"가 아니면 오류가 발생합니다.
이것은 이상한 사양과 같이 보입니다만, 가드에 쓸 수 있는 구문에는, 비교적 제약이 있다(동적인 함수나 자기 정의 함수는 우선 사용할 수 없다) 때문에, 하는 방법은 없습니다
아마도 ``@variables''는 컴파일 타임에 상수이기 때문에이 제약에 걸리지 않을 것입니다.
p.s.「좋아요」 잘 부탁드립니다
페이지 왼쪽 상단의 또는 을 클릭해 주셔서 감사합니다
여기의 숫자가 늘어나면, 필자로서는 「우케하고 있다」라는 감각을 얻을 수 있어 연재를 더욱 진화시켜 나가는 동기 부여가 되기 때문에, 보다 Elixir 재료를 보고 싶다고 하는 당신, 저희와 함께 북돋워 제발!
Reference
이 문제에 관하여(과거 칼럼 ZEN Style화①:재귀로 쓰인 key에 의한 로직 전환(Strategy/State 패턴을 Elixir답게 스마트하게)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/piacerex/items/66c9e533f9701deeb7b4
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여(과거 칼럼 ZEN Style화①:재귀로 쓰인 key에 의한 로직 전환(Strategy/State 패턴을 Elixir답게 스마트하게)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/piacerex/items/66c9e533f9701deeb7b4텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)