我正在研究Dave Thomas(Pragmatic Bookshelf)编写的Elixir中的例子。我一直在http://tryelixir.online/使用REPL,并且在这个特定问题上尝试过Wandbox同样的结果。
defmodule Sequence.Server do
use GenServer
def handle_call( :next_number, _from, current_number ) do
{ :reply, current_number, current_number + 1 }
end
def handle_cast( { :increment_number, delta }, current_number ) do
{ :no_reply, current_number + delta }
end
end
{ :ok, pid } = GenServer.start_link( Sequence.Server, 100 )
GenServer.call( pid, :next_number ) # returns 100
GenServer.call( pid, :next_number ) # returns 101
GenServer.call( pid, :next_number ) # returns 102
GenServer.cast( pid, { :increment_number, 200 } ) # should set the number to 302
GenServer.call( pid, :next_number ) # returns undefined
如果我注释掉GenServer演员,那么最后一次调用将按预期工作。相反,如果我注释掉所有GenServer调用,则转换返回:ok。否则,调用一直有效,直到强制转换为止,并且强制转换后的调用返回undefined。启动服务器时在调试选项上设置跟踪也会确认这一点(当只调用调用或仅调用强制转换时,两者都没有注释)。似乎服务器状态不会在演员表上进行。
此:
...
{ :ok, pid } = GenServer.start_link( Sequence.Server, 100, [ debug: [ :trace ] ] )
#GenServer.call( pid, :next_number ) # returns 100
#GenServer.call( pid, :next_number ) # returns 101
#GenServer.call( pid, :next_number ) # returns 102
GenServer.cast( pid, { :increment_number, 200 } ) # should set the number to 302
#GenServer.call( pid, :next_number ) # returns undefined
返回:
*DBG* <0.1066.0> got cast {increment_number,200}
:ok
虽然这个:
...
{ :ok, pid } = GenServer.start_link( Sequence.Server, 100, [ debug: [ :trace ] ] )
GenServer.call( pid, :next_number ) # returns 100
GenServer.call( pid, :next_number ) # returns 101
GenServer.call( pid, :next_number ) # returns 102
#GenServer.cast( pid, { :increment_number, 200 } ) # should set the number to 302
GenServer.call( pid, :next_number ) # returns undefined
返回:
*DBG* <0.1078.0> got call next_number from <0.1073.0>
*DBG* <0.1078.0> sent 100 to <0.1073.0>, new state 101
*DBG* <0.1078.0> got call next_number from <0.1073.0>
*DBG* <0.1078.0> sent 101 to <0.1073.0>, new state 102
*DBG* <0.1078.0> got call next_number from <0.1073.0>
*DBG* <0.1078.0> sent 102 to <0.1073.0>, new state 103
*DBG* <0.1078.0> got call next_number from <0.1073.0>
*DBG* <0.1078.0> sent 103 to <0.1073.0>, new state 104
103
这里发生了什么?通过在线Elixir文档搜索确认这仍然是cast和handle_cast的有效语法/ arity / etc。本书的在线勘误表中没有任何内容表明存在错误。此行为在至少两个在线REPL中是可重复的。