2009-08-21 19 views
13

xyz çağrılacak bir işlevin adı ile aramak istiyorum.Erlang'da, bir işlevi dinamik olarak nasıl çağırıyorsunuz?

1> c(sample.erl). 
./sample.erl:6: Warning: function p/0 is unused 
./sample.erl:7: Warning: function g/0 is unused 
{ok,sample} 
2> sample:xyz('p'). 
** exception error: bad function p 
    in function sample:xyz/1 
3> 
+2

My Erlang bilgisi sıfıra yakın, ama isterseniz, s (ve muhtemelen g ihracat olduğunu varsayalım bunu kullanmak için). – balpha

cevap

22

Size p ve g ihraç zorunda doğrudur:

-module(sample). 
-export([xyz/1]). 

xyz(Name) -> Name(). 

p() -> "you called p". 
g() -> "you called g". 

Ama aşağıdaki hatayı alıyorum. Daha sonra bunu uygulamak için/3 uygulamasını kullanabilirsiniz.

erlang:apply(sample, p, []) 

Yalnızca eğlence değerleri, Fun (...) sözdizimi ile kullanılabilir. Bir atom değerinde geçiyorsunuz. Hata iletisi giderken bir atom 'kötü işlev' dir. Sen Sonra devam edin

xyz(p) -> fun p/0; 
xyz(g) -> fun g/0. 

benzer bir şey yapmak ve

Fun = xyz(p), 
Fun() 
+0

Teşekkürler. Şimdi bu var: -module (örnek). -export ([xyz/1, p/0, g/0]). xyz (Name) -> uygulayın (örnek, İsim, []). p() -> "siz aradınız". g() -> "g çağırdınız". ve ben yapabiliyorum: 26> c (sample.erl). {ok, örnek} 27> örnek: xyz ('p'). "p" 28> adlı aygıtı çağırdınız. Örnek: xyz (p). "p" 29> adlı aygıtı aradınız ": xyz ('g'). "g" 30> adlı aygıtı çağırdınız. Örnek: xyz (g). "g" aradınız. Ancak bu işlevleri dışa aktarmanın bir yolu yok mu? Modül kullanıcıları için görünmesini istemiyorum. Uygula/2 ile çalışmayı da göremiyorum. Tabii ki, ben bir erlang acemi oldum – ottodidakt

+1

Arama eşlemenizi kalıp eşleştirmeyle sabitleyin ya da işlevlerinizi dışa aktarın. – Zed

+0

İstenmeyen bir işlevi 'sızdırmanıza' tek yolu, kendisine başvuran eğlenceli bir değer döndürmektir. Aynen eğlenceli bir değer döndüren açık xyz/1 işlevim gibi. – Christian

7

Kalıp eşleştirme kullanmak deyim olduğunu diyebiliriz:

-module(sample). 
-export([xyz/1]). 

xyz(p) -> p(); 
xyz(q) -> g(). 

p() -> "you called p". 
g() -> "you called g". 

size kullanabilirsiniz dinamik olmasını istiyorsanız gen_event sunucusu. Daha sonra esas işlevlerine olayları bağlayabilir

[{p, #func1}, 
{g, #func2}, 
{..., ...}, 
...] 

:

Esasen bu ne şöyle anahtar/fonksiyon düzleminden oluşan ve devlet tutan bir sunucudur. (Bundan daha biraz daha, söylemeye gerek yok yoktur.

+1

teknik olarak bunu yapmanın bir yolu olsa da, sorunun dinamik olarak bir işlevi çağırmak için erlang dilinde mekaniğe daha fazla odaklandığını düşünüyorum. Uygulama işlevi, aradığı cevaptır. –

8
-module(sample). 
-export([xyz/1, p/0, g/0]). 

xyz(Name) -> ?MODULE:Name(). 

p() -> "you called p". 
g() -> "you called g". 


1> sample:xyz(p). 
"you called p" 
+1

Bu oldukça havalı. "? MODULE" hakkında nerede okuyabilirim? Şimdi ise sadece p ve q ihraç etmekteydik. – ottodidakt

+0

Önceden tanımlı makrolar: http://erlang.org/doc/reference_manual/macros.html#7.3. Ne yazık ki Erlang sadece "kamu" ve "özel" görünürlük var, ancak korumalı ve paket korumalı değil. Yani ya ihraç edersiniz, ya da çağrıları "kodlarsınız". – Zed

+1

Ancak neden statik olarak bağlı bir çağrı xyz (İsim) -> p() durumunda ihracat yapmam gerekiyor. ve dinamik olarak bağlandığında dışa aktarılması gerekli midir? "Özel" görünürlük açısından düşünmek, özel kapsamdayım, değil mi? – ottodidakt

0

o (size çözdüğümüz problem) işlevlerine dinamik çağrılar üzerine bina ettiği bakmak için başka bir yol olduğunu mutlaka Doğru yaklaşım: Süreç ve mesaj geçişi Erlang'da kodunuzu "eşzamanlılık odaklı bir dil" olduğu için düzenlemenin yolu olduğundan, sıralı bir dilin deyimlerini taklit etmekten ziyade seçici bir mesajla geçen mesajı kullanabilirsin? İstediğiniz şey için ve buna göre özel yanıt alın. Her işlevin sonucuyla ilgili değil, fonksiyonun kendisiyle ilgili. (Artı mesajların geçebilme esnekliği ve ölçeklenebilirliği, vb.)

Alt hough işlemleri bir kütüphane modülünden çağrılmaya kıyasla tamamen özgür değildir, Erlang-seviyesi süreçleri kirletmez (özellikle mesaj iletişimi aynı düğüm içinde ise). İşletim sistemi düzeyinde değiller. Daha yüksek kodlama dillerinde, dinamik işlev çağrıları ve nesne örneklemesi için genel gider karşılaştırılabilir (veya daha iyi) olacaktır.

1

Yapmanın en kolay yolu, xyz ile birlikte p ve g dışa aktarmayı denemektir.

-export([xyz/1, p/0,g/0]). 
aşağıdaki gibi işlev p ve g ihraç çağrılabilir sonra

:

1> sample:xyz(fun sample:p/0). 
"you called p" 
2> sample:xyz(fun sample:g/0). 
"you called g" 
İlgili konular