2017-04-26 38 views
1

我有一個雨傘應用程序,
它在一個應用程序(例如:App1)中發送一個函數作爲參數位於另一個應用程序中的另一個函數(例如:App2 )。
我送的功能是這樣的:在一個雨傘應用程序中使用捕獲操作符 - elixir

defmodule App1.Bar do 
    def bar_bar(fun) do 
    fun.() 
    end 
end 

defmodule App2.Foo do 
    def foo_foo do 
    App1.Bar.bar_bar(&Io.puts(Project.get.project[:app])) 
    end 
end 

我的問題是:
沒有該功能在實際執行App1App2(其中它被定義)?

+0

由於您不是從App1.Bar調用'App2.Bar'的函數,所以可能會出現錯字。 – PatNowak

+0

@PatNowak,謝謝,編輯 – fay

回答

1

這個例子將拋出CompileError,因爲捕捉操作假定您將提供的功能,這將是這樣的:

&Mod.fun/arity 
&local/arity 

,或者至少要指定一個參數爲使用也捕捉運營商如。 &Mod.fun(&1)

在這種情況下,你的觀點是錯誤的。 沒有捕捉操作和使用讓你不得不有匿名函數的常規方式:

fn -> Io.puts(Project.get.project[:app]) end 

所以它會爲Project.get.project[:app]內容合作。我不熟悉那個奇特的模塊,但它應該在你稱之爲的模塊中工作。

+0

當我這樣做你建議fn - > Io.puts(Project.get.project [:app])結束,這將運行的應用程序? – fay

+0

運行此功能的應用程序 - App2。 – PatNowak

2

如果你是做這樣的事情,這將是App1執行,但它會在App2評估

讓我們看看這實際上是什麼意思。假設我們有以下幾個模塊:

defmodule Foo do 
    def foo(fun) do 
    IO.puts "I AM IN FOO" 
    fun.() 
    end 
end 
defmodule Bar do 
    def bar(), do: Foo.foo(fn -> IO.inspect baz() end) 
    defp baz(), do: "baz" 
end 

iex(1)> Bar.bar() 
I AM IN FOO 
"baz" 
"baz" 

的兩個重要組成部分,這裏要注意的:

  • 我們印刷I AM IN FOO之前,我們看到在我們的匿名功能的打印。這意味着該功能在Foo中執行。
  • 我們能夠評估Bar.baz/0,即使Foo無法看到該功能(它也沒有自己的baz/0功能)。這意味着它必須在被傳遞給Foo.foo/1之前進行過評估。
1

要控制的功能被中執行的項目,則可以使用Mix.Project.in_project/4

Mix.Project.in_project :my_app, "/path/to/my_app", fn module -> 
    "Mixfile is: #{inspect module}" 
end 
#=> "Mixfile is: MyApp.Mixfile" 

在功能之間一般通過lambda表達式將保留從拉姆達被定義在詞法作用域。

然而傳遞過程之間的lambda將導致self()評估爲不同的值:

iex(10)> lambda = fn -> IO.puts("Lambda running in: #{inspect(self())}") end 
#Function<20.52032458/0 in :erl_eval.expr/5> 

iex(11)> lambda.() 
Lambda running in: #PID<0.80.0> 
:ok 

iex(12)> spawn(lambda) 
Lambda running in: #PID<0.96.0> 
#PID<0.96.0> 

這可以改變的任何依賴於當前過程字典的輸出,如Ecto.Repo存儲該當前在事務處理中的Process字典中進行連接。

相關問題