<?xml version="1.0" encoding="utf-8"?>
<page xmlns="http://projectmallard.org/1.0/" xmlns:its="http://www.w3.org/2005/11/its" type="topic" id="introspection" xml:lang="cs">

  <info>
    <link type="guide" xref="index#specific-how-tos"/>

    <credit type="author copyright">
      <name>Philip Withnall</name>
      <email its:translate="no">philip.withnall@collabora.co.uk</email>
      <years>2015</years>
    </credit>

    <include xmlns="http://www.w3.org/2001/XInclude" href="cc-by-sa-3-0.xml"/>

    <desc>Podpora introspekce pro GObject v kódu knihovny</desc>
  </info>

  <title>Introspekce</title>

  <synopsis>
    <title>Shrnutí</title>

    <p><link href="https://wiki.gnome.org/Projects/GObjectIntrospection">GObject introspection</link> (zkráceně „GIR“) je systém, který získává API z kódu v jazyce C a na jejich základě vytváří binární knihovny, které můžete použít k navázání jiných programovacích jazyků a v nástrojích pro <link href="https://en.wikipedia.org/wiki/Type_introspection">introspekci</link> nebo <link href="https://cs.wikipedia.org/wiki/Language_Binding">navázání</link> originálních knihoven v C. Používá se k tomu systém anotací v dokumentačních komentářích ve zdrojových kódech, pomocí kterých se zveřejní doplňující informace o API, které jsou přímo z kódu strojově čitelné.</p>

    <p>Mělo by to být zapnuto pro všechna veřejná API, tzn. pro všechny knihovny. Zapnuto by to nemělo být pro programy, protože ty nevystavují žádná API. I tak je ale doporučeno <link xref="documentation#introspection-annotations">přidat anotace k introspekci do dokumentačních komentářů</link> v programovém kódu, aby dokumentace byla jasnější.</p>

    <list>
      <item><p>Povolte introspekci pro všechny knihovny. (<link xref="#using-introspection"/>)</p></item>
      <item><p>Dávejte pozor na varování od <cmd>g-ir-scanner</cmd> a atribut <code>introspectable="0"</code> v souborech GIR. (<link xref="#using-introspection"/>)</p></item>
      <item><p>Přidávejte anotace k introspekci do všech dokumentačních komentářů. (<link xref="#using-introspection"/>)</p></item>
      <item><p>Navrhujte API už od začátku tak, aby v nich šla použít introspekce. (<link xref="#api-design"/>)</p></item>
    </list>
  </synopsis>

  <section id="using-introspection">
    <title>Použití introspekce</title>

    <p>Prvním korkem k použití introspekce je její přidání do sestavovacího systému podle instrukcí uvedených <link href="https://wiki.gnome.org/Projects/GObjectIntrospection/AutotoolsIntegration#Method_1_-_Recommended_-_most_portable">zde</link> v metodě 1. Mělo by se tak stát v rané fázi projektu, protože schopnost introspekce ovlivňuje <link xref="#api-design">návrh API</link>.</p>

    <p>To by se mělo odrazit v souborech <file>.gir</file> a <file>.typelib</file>, které se pro projekt vygenerují. Soubor <file>.gir</file> je člověkem čitelný a můžete jej ručně zkoumat, jestli má API správnou introspekci (ačkoliv proces kompilace GIR vypíše chybové zprávy a varování pro chybějící anotace nebo jiné problémy). API s <code>introspectable="0"</code> nebude zpřístupněno pro vazbu na jazyk, protože mu schází anotace nebo není z jiných důvodů přítomno v souboru GIR.</p>

    <p>Dalším krokem je <link xref="documentation#introspection-annotations">přidat anotace do dokumentačních komentářů pro každou část veřejného API</link>. Pokud některá konkrétní část nemá být v souboru GIR zpřístupněna, použijte anotaci <code>(skip)</code>. Dokumentaci se seznamem dostupných anotací najdete <link href="https://wiki.gnome.org/Projects/GObjectIntrospection/Annotations">zde</link>.</p>

    <p>Když vytváříte anotace kódu pro program, je dobrým zvykem rozdělik hromadu kódu do vhodných interních privátních knihoven. Z dokumentačních komentářů pak můžete sestavit referenční příručku k API (viz <link xref="documentation"/>). Takovéto knihovny se pak neinstalují, ale přímo slinkují s vlastním programem. Přínos vygenerované interní dokumentace oceníte především u velkých projektů, kde interní kód může být opravdu rozsáhlý a těžko se v něm orientuje.</p>

    <p>Anotace by ale neměly být přidávány bezúčelně: GIR má sadu výchozích anotací, které se použijí na základě různých pravidel (viz <link xref="#api-design"/>). Například parametr <code>const gchar*</code> nepotřebuje výslovně uvádět anotaci <code>(transfer none)</code>, protože to dává najevo již modifikátor <code>const</code>. Když se tyto výchozí anotace naučíte, jen to prospěje věci.</p>
  </section>

  <section id="api-design">
    <title>Návrh API</title>

    <p>Aby API podporovalo introspekci bez přílišného množství anotací, musí dodržovat jisté zvyklosti, jako třeba <link href="https://developer.gnome.org/gobject/stable/gtype-conventions.html">standardní konvenci názvů GObject</link> a <link href="https://wiki.gnome.org/Projects/GObjectIntrospection/WritingBindingableAPIs">konvenci pro API podporující vazby na jiné jazyky</link>. To je nutné kvůli flexibilitě C: programový kód, který se chová slušně, může být napsán všemožnými způsoby, ale vysokoúrovňové jazyky tento druh volnosti nedovolují. Takže aby API v jazyce C mohlo být zpřístupněno ve vysokoúrovňovém jazyce, musí se podřídit chování podporovanému tímto jazykem.</p>

    <p>Například GIR očekává, že jestliže funkce může selhat, tak vrací parametr <code>GError**</code>, který je vždy posledním parametrem. Analyzátor GIR takovýto parametr odhalí a automaticky převede atribut výjimky u metody v souboru GIR. Nemůže to ale udělat, pokud je například  <code>GError**</code> vracen přímo nebo není posledním parametrem.</p>

    <p>Proto musí být API navržena pro introspekci a při jejich psaní by měl být překontrolováván soubor GIR. Když GIR neodpovídá tomu, co pro nové API očekáváte, potřebuje API dodatečné anotace nebo i změnu v deklaraci C (jako v případě <link href="https://wiki.gnome.org/Projects/GObjectIntrospection/WritingBindingableAPIs#va_list"><code>va_list</code></link>).</p>

    <p><cmd>g-ir-scanner</cmd> vyšle varování, když narazí na kód, kterému nerozumí. Předání <cmd>--warn-error</cmd> nebo také <cmd>--warn-all</cmd> v <code>INTROSPECTION_SCANNER_ARGS</code> v <file>Makefile.am</file> způsobí, že kompilace selže, když se narazí na API nepodporující introspekci. Tím se zajistí, že nová API budou vždy podporovat introspekci, což je silně doporučováno.</p>
  </section>
</page>
