Elixir 1.7

Inspect.Algebra




elixir

Inspect.Algebra

बीजगणित दस्तावेजों को बनाने और हेरफेर करने के लिए कार्यों का एक सेट।

यह मॉड्यूल क्रिश्चियन लिंडिग द्वारा "स्ट्रिक्टली प्रेटी" (2000) में वर्णित कार्यक्षमता को बाइनरी नोड्स के लिए समर्थन और क्षैतिज मोड के उपयोग को तोड़ने वाले ब्रेक मोड की तरह लागू करता है।

iex> Inspect.Algebra.empty()
:doc_nil

iex> "foo"
"foo"

इस मॉड्यूल में कार्यों के साथ, हम विभिन्न तत्वों को एक साथ जोड़ सकते हैं और उन्हें प्रस्तुत कर सकते हैं:

iex> doc = Inspect.Algebra.concat(Inspect.Algebra.empty(), "foo")
iex> Inspect.Algebra.format(doc, 80)
["foo"]

फ़ंक्शन nest/2 , space/2 और line/2 आपको दस्तावेज़ को एक कठोर संरचना में एक साथ रखने में मदद करते हैं। हालांकि, glue/3 और group/1 जैसे कार्यों का उपयोग करते समय दस्तावेज़ बीजगणित दिलचस्प हो जाता है। एक गोंद दो दस्तावेजों के बीच एक विराम को सम्मिलित करता है। एक समूह एक दस्तावेज़ को इंगित करता है जो वर्तमान लाइन को फिट करना चाहिए, अन्यथा ब्रेक को नई लाइनों के रूप में प्रदान किया जाता है। चलो एक ब्रेक के साथ दो डॉक्स को गोंद करते हैं, इसे समूहित करते हैं और फिर इसे प्रस्तुत करते हैं:

iex> doc = Inspect.Algebra.glue("a", " ", "b")
iex> doc = Inspect.Algebra.group(doc)
iex> Inspect.Algebra.format(doc, 80)
["a", " ", "b"]

ध्यान दें कि ब्रेक का प्रतिनिधित्व किया गया था, क्योंकि हम एक पंक्ति सीमा तक नहीं पहुंचे हैं। एक बार जब हम ऐसा करते हैं, तो इसे एक नई पंक्ति द्वारा बदल दिया जाता है:

iex> doc = Inspect.Algebra.glue(String.duplicate("a", 20), " ", "b")
iex> doc = Inspect.Algebra.group(doc)
iex> Inspect.Algebra.format(doc, 10)
["aaaaaaaaaaaaaaaaaaaa", "\n", "b"]

यह मॉड्यूल बाइट के आकार का उपयोग करके गणना करता है कि कितना स्थान बचा है। यदि आपके दस्तावेज़ में तार हैं, तो उन लोगों को string/1 String.length/1 आवश्यकता होती है, जो तब दस्तावेज़ के आकार को String.length/1 पर निर्भर करते हैं।

अंत में, इस मॉड्यूल में to_doc/2 संबंधित फ़ंक्शन भी शामिल हैं, जो to_doc/2 फॉर्मेटिंग से थोड़ा सा बंधा हुआ है, जैसे कि to_doc/2

कार्यान्वयन का विवरण

इंस्पेक्ट.एल्जेब्रा का कार्यान्वयन लिंडिग द्वारा स्ट्रिक्टली प्रिटी पेपर पर आधारित है, जो पिछले सुंदर प्रिंटिंग एल्गोरिदम के शीर्ष पर है, लेकिन एलिक्जिर जैसी सख्त भाषाओं के अनुरूप है। कागज में मुख्य विचार स्पष्ट दस्तावेज समूहों का उपयोग होता है जो फ्लैट (रिक्त स्थान के रूप में) या ब्रेक के रूप में (न्यूलाइन के रूप में विराम) प्रदान किए जाते हैं।

यह कार्यान्वयन दो प्रकार के ब्रेक प्रदान करता है :strict और :flex । जब एक समूह फिट नहीं होता है, तो सभी सख्त ब्रेक को नई सुर्खियों के रूप में माना जाता है। हालांकि, फ्लेक्स ब्रेक हर घटना पर पुनर्मूल्यांकन किया जाता है और अभी भी फ्लैट प्रदान किया जा सकता है। अधिक जानकारी के लिए break/1 और flex_break/1 देखें।

इस कार्यान्वयन में force_unfit/1 और next_break_fits/2 जो दस्तावेज़ फिटिंग पर अधिक नियंत्रण देते हैं।

सारांश

प्रकार

t()

कार्य

break/1

दिए गए string आधार पर एक विराम दस्तावेज़ लौटाता है

collapse_lines(max)

इस नोड के बाद किसी भी नई लाइनों और व्हाट्सएप को संक्षिप्त करें, max नई लाइनों तक उत्सर्जित करें

रंग (डॉक्टर, color_key, opts)

यदि color_key विकल्पों में रंग है, तो दस्तावेज़ को रंग दें

concat(docs)

एक नए दस्तावेज़ को लौटाने वाले दस्तावेजों की एक सूची को सम्‍मिलित करता है

कंकट (doc1, doc2)

एक नया दस्तावेज़ लौटाने वाले दो दस्तावेज़ संस्थाओं को सम्‍मिलित करता है

कंटेनर_डॉक (बाएं, संग्रह, दाएं, निरीक्षण, मज़ा, ऑप्स \\ [])

सीमा और सामग्री के अनुसार left और right में रैप collection

empty()

एक दस्तावेज़ इकाई का उपयोग करता है जो शून्यता का प्रतिनिधित्व करता है

flex_break/1

दिए गए string आधार पर एक फ्लेक्स ब्रेक दस्तावेज़ लौटाता है

flex_glue (doc1, break_string \\ "", doc2)

Glues दो दस्तावेज़ ( doc1 और doc2 ), उनके बीच break_string द्वारा दिए गए flex_break/1 को सम्मिलित करते हैं

fold_doc (डॉक्स, folder_fun)

दिए गए फ़ोल्डर फ़ंक्शन का उपयोग करके दस्तावेज़ में दस्तावेजों की एक सूची को तह करता है

force_unfit/1

वर्तमान समूह को अयोग्य होने के लिए मजबूर करता है

प्रारूप (डॉक्टर, चौड़ाई)

किसी दिए गए चौड़ाई के लिए दिए गए दस्तावेज़ को प्रारूपित करता है

glue/3

Glues दो दस्तावेज़ ( doc1 और doc2 ) उनके बीच दिए गए ब्रेक break_string सम्मिलित करते हैं

समूह (डॉक्टर, मोड \\: स्व)

निर्दिष्ट दस्तावेज़ doc युक्त समूह देता है

is_doc(doc)
line()

एक अनिवार्य लाइनब्रेक

line/2

दो दस्तावेजों के बीच एक अनिवार्य लाइनब्रेक सम्मिलित करता है

घोंसला (डॉक्टर, स्तर, मोड \\: हमेशा)

दिए गए दस्तावेज़ को दिए गए level

next_break_fits/2

अगले ब्रेक को फिट मानते हैं

space/2

दो दस्तावेजों के बीच एक अनिवार्य एकल स्थान सम्मिलित करता है

string/1

एक स्ट्रिंग द्वारा प्रस्तुत दस्तावेज़ बनाता है

to_doc/2

Inspect प्रोटोकॉल के अनुसार एक बीजगणित दस्तावेज़ में एक अमृत शब्द Inspect है

प्रकार

टी ()

t() ::
  binary()
  | :doc_nil
  | :doc_line
  | doc_string()
  | doc_cons()
  | doc_nest()
  | doc_break()
  | doc_group()
  | doc_color()
  | doc_force()
  | doc_fits()
  | doc_collapse()

कार्य

ब्रेक (स्ट्रिंग \\ "")

break(binary()) :: doc_break()

दिए गए string आधार पर एक विराम दस्तावेज़ लौटाता है।

चुने हुए लेआउट के mode के आधार पर, इस ब्रेक को एक लाइनब्रेक या दिए गए string रूप में प्रदान किया जा सकता है।

उदाहरण

आइए उनके बीच एक विराम के साथ दो तारों को जोड़कर एक दस्तावेज़ बनाएं:

iex> doc = Inspect.Algebra.concat(["a", Inspect.Algebra.break("\t"), "b"])
iex> Inspect.Algebra.format(doc, 80)
["a", "\t", "b"]

ध्यान दें कि ब्रेक को दिए गए स्ट्रिंग के साथ दर्शाया गया था, क्योंकि हम एक पंक्ति सीमा तक नहीं पहुंचे थे। एक बार जब हम ऐसा करते हैं, तो इसे एक नई पंक्ति द्वारा बदल दिया जाता है:

iex> break = Inspect.Algebra.break("\t")
iex> doc = Inspect.Algebra.concat([String.duplicate("a", 20), break, "b"])
iex> doc = Inspect.Algebra.group(doc)
iex> Inspect.Algebra.format(doc, 10)
["aaaaaaaaaaaaaaaaaaaa", "\n", "b"]

पतन_लाइन्स (अधिकतम) (1.6.0 के बाद से)

collapse_lines(pos_integer()) :: doc_collapse()

इस नोड के बाद किसी भी नई लाइनों और व्हाट्सएप को संक्षिप्त करें, max नई लाइनों तक उत्सर्जित करें।

रंग (डॉक्टर, color_key, opts) (1.4.0 के बाद से)

color(t(), Inspect.Opts.color_key(), Inspect.Opts.t()) :: doc_color()

यदि color_key विकल्पों में रंग है, तो दस्तावेज़ को रंग दें।

concat (दस्तावेज़)

concat([t()]) :: t()

एक नए दस्तावेज़ को लौटाने वाले दस्तावेजों की एक सूची को सम्‍मिलित करता है।

उदाहरण

iex> doc = Inspect.Algebra.concat(["a", "b", "c"])
iex> Inspect.Algebra.format(doc, 80)
["a", "b", "c"]

कंकट (doc1, doc2)

concat(t(), t()) :: t()

एक नया दस्तावेज़ लौटाने वाले दो दस्तावेज़ संस्थाओं को सम्‍मिलित करता है।

उदाहरण

iex> doc = Inspect.Algebra.concat("hello", "world")
iex> Inspect.Algebra.format(doc, 80)
["hello", "world"]

कंटेनर_डॉक (बाएं, संग्रह, दाएं, निरीक्षण, मज़ा, ऑप्स \\ []) (1.6.0 के बाद से)

container_doc(
  t(),
  [any()],
  t(),
  Inspect.Opts.t(),
  (term(), Inspect.Opts.t() -> t()),
  keyword()
) :: t()

सीमा और सामग्री के अनुसार left और right में रैप collection

यह दिए गए left और right दस्तावेज़ों को आस-पास और विभाजक दस्तावेज़ separator को docs में अलग-अलग मदों के रूप में उपयोग करता है। यदि संग्रह में सभी प्रविष्टियां सरल दस्तावेज (ग्रंथ या तार) हैं, तो यह फ़ंक्शन एक ही पंक्ति में जितना संभव हो उतना डालने का प्रयास करता है। यदि वे सरल नहीं हैं, तो केवल एक प्रविष्टि प्रति पंक्ति दिखाई जाती है यदि वे फिट नहीं हैं।

दिए गए Inspect.Opts की सीमा का सम्मान किया जाता है और जब यह फ़ंक्शन Inspect.Opts है तो प्रोसेसिंग और आउटपुट को रोक देता है "..." बजाय।

विकल्प

  • :separator - विभाजक प्रत्येक डॉक्टर के बीच उपयोग किया जाता है
  • :break - यदि :strict , हमेशा प्रत्येक तत्व के बीच विराम। यदि :flex , केवल आवश्यक होने पर टूट जाता है। यदि :maybe , चुनता है :flex केवल अगर सभी तत्व पाठ-आधारित हैं, अन्यथा :strict

उदाहरण

iex> doc = Inspect.Algebra.container_doc("[", Enum.to_list(1..5), "]",
...>         %Inspect.Opts{limit: :infinity}, fn i, _opts -> to_string(i) end)
iex> Inspect.Algebra.format(doc, 5) |> IO.iodata_to_binary()
"[1,\n 2,\n 3,\n 4,\n 5]"

iex> doc = Inspect.Algebra.container_doc("[", Enum.to_list(1..5), "]",
...>         %Inspect.Opts{limit: 3}, fn i, _opts -> to_string(i) end)
iex> Inspect.Algebra.format(doc, 20) |> IO.iodata_to_binary()
"[1, 2, 3, ...]"

iex> doc = Inspect.Algebra.container_doc("[", Enum.to_list(1..5), "]",
...>         %Inspect.Opts{limit: 3}, fn i, _opts -> to_string(i) end, separator: "!")
iex> Inspect.Algebra.format(doc, 20) |> IO.iodata_to_binary()
"[1! 2! 3! ...]"

खाली ()

empty() :: :doc_nil

एक दस्तावेज़ इकाई का उपयोग करता है जो शून्यता का प्रतिनिधित्व करता है।

उदाहरण

iex> Inspect.Algebra.empty()
:doc_nil

flex_break (string \\ "") (1.6.0 के बाद से)

flex_break(binary()) :: doc_break()

दिए गए string आधार पर एक फ्लेक्स ब्रेक दस्तावेज़ लौटाता है।

एक फ्लेक्स ब्रेक अभी भी एक समूह को तोड़ने का कारण बनता है, जैसे कि break/1 , लेकिन दस्तावेज का प्रतिपादन होने पर इसका पुनर्मूल्यांकन किया जाता है।

उदाहरण के लिए, एक समूह दस्तावेज़ को [1, 2, 3] रूप में दर्शाया गया है जहाँ हर अल्पविराम के बाद का स्थान विराम है। जब ऊपर का दस्तावेज़ एक पंक्ति में फिट नहीं होता है, तो सभी ब्रेक सक्षम होते हैं, जिससे दस्तावेज़ को निम्न रूप में प्रस्तुत किया जाता है:

[1,
 2,
 3]

हालाँकि, यदि फ्लेक्स ब्रेक का उपयोग किया जाता है, तो प्रत्येक ब्रेक का मूल्यांकन करते समय पुनर्मूल्यांकन किया जाता है, इसलिए दस्तावेज़ को निम्न रूप से प्रस्तुत किया जा सकता है:

[1, 2,
 3]

इसलिए "फ्लेक्स" नाम। जब वे दस्तावेज़ में आते हैं तो वे अधिक लचीले होते हैं। दूसरी ओर, वे अधिक महंगे हैं क्योंकि प्रत्येक ब्रेक को फिर से मूल्यांकन करने की आवश्यकता होती है।

इस फ़ंक्शन का उपयोग container_doc/4 और दोस्तों द्वारा एक ही पंक्ति में अधिकतम प्रविष्टियों के लिए किया जाता है।

flex_glue (doc1, break_string \\ "", doc2) (1.6.0 से)

flex_glue(t(), binary(), t()) :: t()

Glues दो दस्तावेज़ ( doc1 और doc2 ), उनके बीच break_string द्वारा दिए गए flex_break/1 को सम्मिलित करते हैं।

इस फ़ंक्शन का उपयोग container_doc/6 और दोस्तों द्वारा एक ही पंक्ति में अधिकतम प्रविष्टियों के लिए किया जाता है।

fold_doc (डॉक्स, folder_fun)

fold_doc([t()], (t(), t() -> t())) :: t()

दिए गए फ़ोल्डर फ़ंक्शन का उपयोग करके दस्तावेज़ में दस्तावेजों की एक सूची को तह करता है।

दस्तावेजों की सूची "दाईं ओर" से मुड़ी हुई है; उस में, यह फ़ंक्शन List.foldr/3 समान है, सिवाय इसके कि यह एक प्रारंभिक संचायक की अपेक्षा नहीं करता है और प्रारंभिक संचयक के रूप में docs के अंतिम तत्व का उपयोग करता है।

उदाहरण

iex> docs = ["A", "B", "C"]
iex> docs = Inspect.Algebra.fold_doc(docs, fn(doc, acc) ->
...>   Inspect.Algebra.concat([doc, "!", acc])
...> end)
iex> Inspect.Algebra.format(docs, 80)
["A", "!", "B", "!", "C"]

Force_unfit (doc) (1.6.0 से)

force_unfit(t()) :: doc_force()

वर्तमान समूह को अयोग्य होने के लिए मजबूर करता है।

प्रारूप (डॉक्टर, चौड़ाई)

format(t(), non_neg_integer() | :infinity) :: iodata()

किसी दिए गए चौड़ाई के लिए दिए गए दस्तावेज़ को प्रारूपित करता है।

अपने तर्कों के रूप में मुद्रित करने के लिए अधिकतम चौड़ाई और एक दस्तावेज़ लेता है और दिए गए चौड़ाई में फिट होने के लिए दस्तावेज़ के लिए सर्वोत्तम लेआउट का एक IO डेटा प्रतिनिधित्व लौटाता है।

समूह मिलने तक दस्तावेज़ सपाट (विराम के बिना) शुरू होता है।

उदाहरण

iex> doc = Inspect.Algebra.glue("hello", " ", "world")
iex> doc = Inspect.Algebra.group(doc)
iex> doc |> Inspect.Algebra.format(30) |> IO.iodata_to_binary()
"hello world"
iex> doc |> Inspect.Algebra.format(10) |> IO.iodata_to_binary()
"hello\nworld"

गोंद (doc1, break_string \\ "", doc2)

glue(t(), binary(), t()) :: t()

Glues दो दस्तावेज़ ( doc1 और doc2 ) उनके बीच दिए गए ब्रेक break_string सम्मिलित करते हैं।

ब्रेक कैसे डाला जाता है, इस बारे में अधिक जानकारी के लिए, break/1

उदाहरण

iex> doc = Inspect.Algebra.glue("hello", "world")
iex> Inspect.Algebra.format(doc, 80)
["hello", " ", "world"]

iex> doc = Inspect.Algebra.glue("hello", "\t", "world")
iex> Inspect.Algebra.format(doc, 80)
["hello", "\t", "world"]

समूह (डॉक्टर, मोड \\: स्व)

निर्दिष्ट दस्तावेज़ doc युक्त समूह देता है।

एक समूह में दस्तावेजों को रेंडरर क्षमता के सर्वश्रेष्ठ के लिए एक साथ प्रस्तुत करने का प्रयास किया जाता है।

समूह मोड को भी सेट किया जा सकता है :inherit , जिसका अर्थ है कि यह स्वचालित रूप से टूट जाता है यदि मूल समूह भी टूट गया है।

उदाहरण

iex> doc = Inspect.Algebra.group(
...>   Inspect.Algebra.concat(
...>     Inspect.Algebra.group(
...>       Inspect.Algebra.concat(
...>         "Hello,",
...>         Inspect.Algebra.concat(
...>           Inspect.Algebra.break,
...>           "A"
...>         )
...>       )
...>     ),
...>     Inspect.Algebra.concat(
...>       Inspect.Algebra.break,
...>       "B"
...>     )
...> ))
iex> Inspect.Algebra.format(doc, 80)
["Hello,", " ", "A", " ", "B"]
iex> Inspect.Algebra.format(doc, 6)
["Hello,", "\n", "A", "\n", "B"]

is_doc (doc) (मैक्रो)

लाइन () (1.6.0 से)

line() :: t()

एक अनिवार्य लाइनब्रेक।

यदि लाइन में सभी समूह फिट होते हैं, तो लाइनब्रेक वाला एक समूह फिट होगा।

उदाहरण

iex> doc =
...>   Inspect.Algebra.concat(
...>     Inspect.Algebra.concat(
...>       "Hughes",
...>       Inspect.Algebra.line()
...>     ), "Wadler"
...>   )
iex> Inspect.Algebra.format(doc, 80)
["Hughes", "\n", "Wadler"]

लाइन (doc1, doc2)

line(t(), t()) :: t()

दो दस्तावेजों के बीच एक अनिवार्य लाइनब्रेक सम्मिलित करता है।

line/1 देखें।

उदाहरण

iex> doc = Inspect.Algebra.line("Hughes", "Wadler")
iex> Inspect.Algebra.format(doc, 80)
["Hughes", "\n", "Wadler"]

घोंसला (डॉक्टर, स्तर, मोड \\: हमेशा)

दिए गए दस्तावेज़ को दिए गए level

यदि level एक पूर्णांक है, तो जब भी वे होते हैं, तो इंडेंटेशन को लाइन ब्रेक से जोड़ा जाता है। यदि स्तर है :cursor , दस्तावेज़ में "कर्सर" की वर्तमान स्थिति नेस्टिंग बन जाती है। यदि स्तर है :reset , यह 0 पर वापस सेट है।

mode हो सकता है :always , जिसका अर्थ है नेस्टिंग हमेशा होता है, या :break , जिसका अर्थ है नेस्टिंग केवल एक समूह के अंदर होता है जिसे :break दिया गया है।

उदाहरण

iex> doc = Inspect.Algebra.nest(Inspect.Algebra.glue("hello", "world"), 5)
iex> doc = Inspect.Algebra.group(doc)
iex> Inspect.Algebra.format(doc, 5)
["hello", "\n     ", "world"]

next_break_fits (डॉक्टर, मोड \\: सक्षम) (1.6.0 के बाद से)

अगले ब्रेक को फिट मानते हैं।

mode हो सकता है :enabled या :disabled । जब :enabled , तो यह दस्तावेज़ पर विचार करेगा जैसे ही यह अगला ब्रेक पाता है, प्रभावी रूप से ब्रेक को रद्द करता है। यह अगले ब्रेक की तलाश में किसी भी force_unfit/1 को भी नजरअंदाज करेगा।

अक्षम होने पर, यह हमेशा की तरह व्यवहार करता है और यह किसी भी अगले next_break_fits/2 निर्देश की उपेक्षा करेगा।

उदाहरण

यह कुछ विशिष्ट स्थानों पर कोड तोड़ने से बचने के लिए एलिक्सिर के कोड फॉर्मेटर द्वारा उपयोग किया जाता है। उदाहरण के लिए, इस कोड पर विचार करें:

some_function_call(%{..., key: value, ...})

अब कल्पना करें कि यह कोड इसकी रेखा के अनुरूप नहीं है। कोड फ़ॉर्मेटर %{ ( और ) और %{ और } अंदर विराम का परिचय देता है। इसलिए दस्तावेज़ टूट जाएगा:

some_function_call(
  %{
    ...,
    key: value,
    ...
  }
)

फ़ॉर्मेटर बीजगणित दस्तावेज़ को next_break_fits/1 में मानचित्र का प्रतिनिधित्व करता है ताकि कोड को इस रूप में स्वरूपित किया जाए:

some_function_call(%{
  ...,
  key: value,
  ...
})

अंतरिक्ष (doc1, doc2)

space(t(), t()) :: t()

दो दस्तावेजों के बीच एक अनिवार्य एकल स्थान सम्मिलित करता है।

उदाहरण

iex> doc = Inspect.Algebra.space("Hughes", "Wadler")
iex> Inspect.Algebra.format(doc, 5)
["Hughes", " ", "Wadler"]

स्ट्रिंग (स्ट्रिंग) (1.6.0 के बाद से)

string(String.t()) :: doc_string()

एक स्ट्रिंग द्वारा प्रस्तुत दस्तावेज़ बनाता है।

Inspect.Algebra करते समय। Inspect.Algebra , दस्तावेजों के रूप में बायनेरिज़ को स्वीकार करता है, जिन्हें बाइनरी आकार द्वारा गिना जाता है। दूसरी ओर, string दस्तावेजों को दस्तावेज़ आकार की ओर अंगूर के संदर्भ में मापा जाता है।

उदाहरण

निम्नलिखित दस्तावेज़ में 10 बाइट्स हैं और इसलिए यह बिना ब्रेक के चौड़ाई 9 का प्रारूप नहीं देता है:

iex> doc = Inspect.Algebra.glue("olá", " ", "mundo")
iex> doc = Inspect.Algebra.group(doc)
iex> Inspect.Algebra.format(doc, 9)
["olá", "\n", "mundo"]

हालांकि, अगर हम string उपयोग करते हैं, तो स्ट्रिंग लंबाई का उपयोग किया जाता है, बाइट आकार के बजाय, सही ढंग से फिटिंग:

iex> string = Inspect.Algebra.string("olá")
iex> doc = Inspect.Algebra.glue(string, " ", "mundo")
iex> doc = Inspect.Algebra.group(doc)
iex> Inspect.Algebra.format(doc, 9)
["olá", " ", "mundo"]

to_doc (शब्द, ऑप्स)

to_doc(any(), Inspect.Opts.t()) :: t()

Inspect प्रोटोकॉल के अनुसार एक बीजगणित दस्तावेज़ में एक अमृत शब्द Inspect है।