Erlang 21 - 9. Preprocessor

9 प्रीप्रोसेसर




erlang

9 प्रीप्रोसेसर

9.1 फ़ाइल समावेशन

एक फ़ाइल को निम्नानुसार शामिल किया जा सकता है:

-include(File).
-include_lib(File).

File , एक स्ट्रिंग, एक फ़ाइल को इंगित करना है। इस फ़ाइल की सामग्री निर्देश के स्थान पर, जैसी भी हो, शामिल हैं।

शामिल फ़ाइलों को आमतौर पर रिकॉर्ड और मैक्रो परिभाषाओं के लिए उपयोग किया जाता है जो कई मॉड्यूल द्वारा साझा किए जाते हैं। इसमें शामिल फ़ाइलों के लिए फ़ाइल नाम एक्सटेंशन .hrl का उपयोग करने की अनुशंसा की जाती है।

File कुछ स्ट्रिंग VAR लिए पथ घटक $VAR साथ शुरू हो सकती है। यदि ऐसा है, तो os:getenv(VAR) द्वारा प्राप्त पर्यावरण चर VAR का मान os:getenv(VAR) को $VAR लिए प्रतिस्थापित किया जाता है। यदि os:getenv(VAR) false , तो $VAR छोड़ दिया गया है।

यदि फ़ाइल नाम File निरपेक्ष है (संभवतः चर प्रतिस्थापन के बाद), उस नाम के साथ फ़ाइल शामिल करें। अन्यथा, निर्दिष्ट फ़ाइल को निम्न निर्देशिकाओं में और इस क्रम में खोजा जाता है:

  • वर्तमान कार्य निर्देशिका
  • निर्देशिका जहां मॉड्यूल संकलित किया जा रहा है
  • निर्देशिका include विकल्प include

विवरण के लिए, ERTS erlc(1) मैनुअल पेज को ERTS में देखें और कंपाइलर में compile(3) मैनुअल पेज compile(3)

उदाहरण:

-include("my_records.hrl").
-include("incdir/my_records.hrl").
-include("/home/user/proj/my_records.hrl").
-include("$PROJ_ROOT/my_records.hrl").

include_lib include करने के लिए समान है, लेकिन एक निरपेक्ष फ़ाइल को इंगित करने के लिए नहीं है। इसके बजाय, पहले पथ घटक (संभवतः चर प्रतिस्थापन के बाद) को एक अनुप्रयोग का नाम माना जाता है।

उदाहरण:

-include_lib("kernel/include/file.hrl").

कोड सर्वर कोड का उपयोग करता है code:lib_dir(kernel) के वर्तमान (नवीनतम) संस्करण की निर्देशिका को खोजने के लिए, और फिर उपनिर्देशिका include फ़ाइल file.hrl लिए खोज की file.hrl

9.2 मैक्रोज़ को परिभाषित करना और उनका उपयोग करना

एक मैक्रो को निम्नानुसार परिभाषित किया गया है:

-define(Const, Replacement).
-define(Func(Var1,...,VarN), Replacement).

मॉड्यूल की विशेषताओं और फ़ंक्शन घोषणाओं के बीच एक मैक्रो परिभाषा को कहीं भी रखा जा सकता है, लेकिन परिभाषा मैक्रो के किसी भी उपयोग से पहले आना चाहिए।

यदि एक मैक्रो का उपयोग कई मॉड्यूल में किया जाता है, तो यह अनुशंसा की जाती है कि मैक्रो परिभाषा को किसी फ़ाइल में रखा जाए।

एक मैक्रो का उपयोग निम्नानुसार किया जाता है:

?Const
?Func(Arg1,...,ArgN)

संकलन के दौरान मैक्रोज़ का विस्तार किया जाता है। एक साधारण मैक्रो ?Const को Replacement साथ बदल दिया गया है।

उदाहरण:

-define(TIMEOUT, 200).
...
call(Request) ->
    server:call(refserver, Request, ?TIMEOUT).

इसका विस्तार किया गया है:

call(Request) ->
    server:call(refserver, Request, 200).

एक मैक्रो ?Func(Arg1,...,ArgN) को Replacement से बदल दिया जाता है, जहां मैक्रो परिभाषा से एक चर Var सभी घटनाओं को संबंधित तर्क Arg साथ बदल दिया जाता है।

उदाहरण:

-define(MACRO1(X, Y), {a, X, b, Y}).
...
bar(X) ->
    ?MACRO1(a, b),
    ?MACRO1(X, 123)

इसका विस्तार किया गया है:

bar(X) ->
    {a,a,b,b},
    {a,X,b,123}.

यह अच्छी प्रोग्रामिंग प्रैक्टिस है, लेकिन अनिवार्य नहीं है, यह सुनिश्चित करने के लिए कि एक स्थूल परिभाषा एक वैध एर्लांग वाक्य रचना रूप है।

मैक्रो विस्तार के परिणाम को देखने के लिए, एक मॉड्यूल को 'P' विकल्प के साथ संकलित किया जा सकता है। compile:file(File, ['P']) । यह फ़ाइल File.P में प्रीप्रोसेसिंग और पार्स ट्रांस्फ़ॉर्म के बाद पार्स कोड की सूची तैयार करता है।

9.3 पूर्वनिर्धारित मैक्रों

निम्नलिखित मैक्रो पूर्वनिर्धारित हैं:

?MODULE
वर्तमान मॉड्यूल का नाम।
?MODULE_STRING
वर्तमान मॉड्यूल का नाम, एक स्ट्रिंग के रूप में।
?FILE
वर्तमान मॉड्यूल का फ़ाइल नाम।
?LINE
वर्तमान लाइन संख्या।
?MACHINE
मशीन का नाम, 'BEAM'
?FUNCTION_NAME
वर्तमान फ़ंक्शन का नाम।
?FUNCTION_ARITY
वर्तमान फ़ंक्शन के लिए तर्क (तर्कों की संख्या)।
?OTP_RELEASE
OTP रिलीज़ जो वर्तमान में ईआरटीएस एप्लिकेशन को निष्पादित कर रहा है, पूर्णांक के रूप में इसका हिस्सा है। विवरण के लिए, erlang:system_info(otp_release) । यह मैक्रो OTP रिलीज़ 21 में पेश किया गया था।

9.4 मैक्रो ओवरलोडिंग

पूर्वनिर्धारित मैक्रोज़ को छोड़कर मैक्रोज़ को अधिभार देना संभव है। एक अतिभारित मैक्रो में एक से अधिक परिभाषाएं होती हैं, जिनमें से प्रत्येक में विभिन्न तर्क होते हैं।

फीचर को Erlang 5.7.5 / OTP R13B04 में जोड़ा गया था।

एक मैक्रो ?Func(Arg1,...,ArgN) तर्कों की सूची (संभवतः खाली) एक त्रुटि संदेश में परिणाम देती है यदि तर्कों के साथ ?Func(Arg1,...,ArgN) कम से कम एक परिभाषा है, लेकिन एन तर्कों के साथ कोई नहीं।

इन परिभाषाओं को मानते हुए:

-define(F0(), c).
-define(F1(A), A).
-define(C, m:f).

निम्नलिखित काम नहीं करता है:

f0() ->
    ?F0. % No, an empty list of arguments expected.

f1(A) ->
    ?F1(A, A). % No, exactly one argument expected.

दूसरी ओर,

f() ->
    ?C().

तक विस्तारित है

f() ->
    m:f().

9.5 मैक्रो में फ्लो कंट्रोल

निम्नलिखित मैक्रो निर्देशों की आपूर्ति की जाती है:

-undef(Macro).
स्थूल को ऐसा व्यवहार करता है मानो उसे कभी परिभाषित नहीं किया गया हो।
-ifdef(Macro).
केवल Macro परिभाषित होने पर निम्न पंक्तियों का मूल्यांकन करें।
-ifndef(Macro).
केवल Macro परिभाषित नहीं होने पर निम्न पंक्तियों का मूल्यांकन करें।
-else.
केवल एक ifdef या ifndef निर्देश के बाद अनुमति दी जाती है। यदि वह स्थिति गलत है, तो इसके बजाय else लाइनों का मूल्यांकन किया जाता है।
-endif.
एक ifdef , एक ifndef निर्देश, या if या elif निर्देश के अंत को निर्दिष्ट करता है।
-if(Condition).
निम्न पंक्तियों का मूल्यांकन केवल तभी करता है जब Condition सत्य का मूल्यांकन करती है।
-elif(Condition).
केवल एक या एक और elif निर्देश के बाद अनुमति दी। यदि पूर्ववर्ती if या elif निर्देश सत्य का मूल्यांकन नहीं करते हैं, और Condition सत्य का मूल्यांकन करती है, तो इसके बजाय elif अनुसरण करने वाली रेखाओं का मूल्यांकन किया जाता है।
ध्यान दें

मैक्रो निर्देशों का उपयोग फ़ंक्शंस के अंदर नहीं किया जा सकता है।

उदाहरण:

-module(m).
...

-ifdef(debug).
-define(LOG(X), io:format("{~p,~p}: ~p~n", [?MODULE,?LINE,X])).
-else.
-define(LOG(X), true).
-endif.

...

जब ट्रेस आउटपुट वांछित होता है, तो debug को तब परिभाषित किया जाता है जब मॉड्यूल m संकलित किया जाता है:

% erlc -Ddebug m.erl

or

1> c(m, {d, debug}).
{ok,m}

?LOG(Arg) को फिर io:format/2 लिए एक कॉल में विस्तारित किया जाता है और उपयोगकर्ता को कुछ सरल ट्रेस आउटपुट प्रदान करता है।

उदाहरण:

-module(m)
...
-ifdef(OTP_RELEASE).
  %% OTP 21 or higher
  -if(?OTP_RELEASE >= 22).
    %% Code that will work in OTP 22 or higher
  -elif(?OTP_RELEASE >= 21).
    %% Code that will work in OTP 21 or higher
  -endif.
-else.
  %% OTP 20 or lower.
-endif.
...

कोड रिलीज के आधार पर कोड को सशर्त रूप से चयन करने के लिए OTP_RELEASE मैक्रो का उपयोग करता है।

9.6 -रोर () और -वरिंग () निर्देश

निर्देश- -error(Term) एक संकलन त्रुटि का कारण बनता है।

उदाहरण:

-module(t).
-export([version/0]).

-ifdef(VERSION).
version() -> ?VERSION.
-else.
-error("Macro VERSION must be defined.").
version() -> "".
-endif.

त्रुटि संदेश इस तरह दिखेगा:

% erlc t.erl
t.erl:7: -error("Macro VERSION must be defined.").

निर्देश -warning(Term) एक संकलन चेतावनी का कारण बनता है।

उदाहरण:

-module(t).
-export([version/0]).

-ifndef(VERSION).
-warning("Macro VERSION not defined -- using default version.").
-define(VERSION, "0").
-endif.
version() -> ?VERSION.

चेतावनी संदेश इस तरह दिखेगा:

% erlc t.erl
t.erl:5: Warning: -warning("Macro VERSION not defined -- using default version.").

ओटीपी 19 में -error() और -warning() निर्देश जोड़े गए।

9.7 स्थूल मैक्रो तर्क

निर्माण ??Arg , जहाँ Arg एक स्थूल तर्क है, का विस्तार एक स्ट्रिंग में होता है जिसमें तर्क का टोकन होता है। यह #arg में #arg निर्माण के समान है।

उदाहरण:

-define(TESTCALL(Call), io:format("Call ~s: ~w~n", [??Call, Call])).

?TESTCALL(myfunction(1,2)),
?TESTCALL(you:function(2,1)).

का परिणाम

io:format("Call ~s: ~w~n",["myfunction ( 1 , 2 )",myfunction(1,2)]),
io:format("Call ~s: ~w~n",["you : function ( 2 , 1 )",you:function(2,1)]).

यही है, एक ट्रेस आउटपुट, दोनों फ़ंक्शन के साथ और परिणामी मूल्य।