cosa cambia tra \edef e \let?

  • Creatore
    Topic
  • #121472
    mattiaca
    Partecipante
      Up
      0
      Down
      ::


      Mi sto documentando un po’ sulle primitive tex per personalizzare qualche macro sopratutto quando utilizzo pgf e tikz per il disegno.
      Leggendo qua e là nella documentazione mi sono imbattuto nelle dichiarazioni in oggetto, ma sinceramente mi sfugge la loro differenza, cioè quando va utilizzata l’una o l’altra.
      Apparentemente \let copia il comando espandendolo proprio come fa edef, o mi sbaglio?
      Ecco un emc:
      `
      \documentclass{article}
      \begin{document}
      \def\a{aaa}
      \edef\b{\a}
      \let\c\a
      \def\d{\a}
      \a \space \b \space \c \space \d \par
      \def\a{ccc}
      \a \space \b \space \c \space \d \par
      \end{document}
      `

      Grazie a chi voglia rispondere a questa apparente banalità.

    Visualizzazione 1 filone di risposte
    • Autore
      Risposte
      • #121473
        OldClaudio
        Partecipante
          Up
          0
          Down
          ::


          Ti sbagli.

          \let crea un nome alias per un dato comando e ci sono vari motivo per usare un alias; il più frequentemente usato è l’uso di \let per dare un alias alle graffe:`\let\bgroup={
          \let\egroup=}` usare \bgroup ed \egroup piuttosto delle graffe nude e crude permette di ottenere lo stesso effetto: raggruppare quanto contenuto fra le graffe o quanto è contenuto tra i deu alias. Ma se l’effetto è lo stesso, a cosa serve disporre di un alias? Per uno scopo importantissimo; quando l’iterpreta espande una macro richiede che le graffe siano accuratamente appaiate; me se un gruppo si apre con una macro e lo si chiude con un’altra macro? Chi mai farebbe una sciocchezza del genere? Semplice; qualunque ambiente usa una macro per essere aperto e una seconda macro per essere chiuso \quindi \bgroup può stare fra i comandi di apertura e \egroup fra i comandi di chiusura; l’interprete non li rileva come graffe, ma al momento di sviluppare quelle macro usa benissimo quegli alias come graffe.

          \edef, invece definisce un comando sviluppando la sua definizione; un esempio che ricorre spesso nel nucleodi LaTeX, ma che anch’io uso spesso nelle mie macro, è il seguente:`
          \newcommand\pippo[#1]{ bla bla bla
          \bgroup
          \edef\x{\egroup \the#1}\x
          blo blo blo}`

          Naturalmente quanto costituisce bla bla bla e blo blo blo non ha importanza in questo esempio, ‘importante è che blo blo blo ha bisogno di usare il vero contenuto di #1 e non si accontenta del segnaposto dell’argomento; inoltre \newcommand è una macro \LaTeX, ma l’esempio funzionerebbe lo stesso se scrivessi [tt]\def\pippo#1{ bla bla bla…}\/tt]

          Che cosa fa quell’acrobazia? Apre un gruppo con \bgroup; poi definisce \x con lo sviluppo della sua definizione; \non sviluppa \egroup perché non è sviluppabile,ma sviluppa #1; se per esempio se l’argomento #1 fosse una control sequence che si riferisce ad una lunghezza, per esempio \hsize (la giustezza corrente), ebbene lo sviluppo di \the#1 potrebbe essere 350\pt, quindi lo sviluppo di \x sarebbe “\egroup 350pt”; quando \x viene eseguito per prima cosa chiude il gruppo cancellando se stessa dalla memoria delle macro, e usa solo la parte 350[t, senza lasciare tracce dietro di se. Gli esempi che trovi nel nucleo di \LaTeX sono numerosissimi; merita aprire il file laex.ltx con il tuo solito ediotor (lo trovi in …/tex/latex/base — i puntini cambiano a seconda che usi TeX Live o MiKTeX e che tu sia su una piattaforma Windows, Mac o Linux).

          Un altro uso particolare potrebbe essere il seguente`\let\originalambiene\ambiente \let\endoriginalambiente\endambiente
          \renewengironment{ambiente}[1]{\begin{originalambiente{#1}{\end(originalambiente}`

          Dopo aver conservato con gli alias i comandi di apertura e di chiusura dell’ “ambiente”, puoi ridefinire l’ambiente senza perdere al possibilità di conservare le funzionalità dell’ambiente originale al quale hai solo cambiato nome perché gli alias non sono stati ridefiniti e sono perfettamente disponibili.

          Prova a farti qualche essmpio più sensato e metti in pratica queste differenze sostanziali fra let e \edef.

          Per vedere in confronti usa [tt]\show\commando[/tt] o [tt\ShowCommand\comando[/tt]. Vedrai che cosa succede degli alias e dei comandi definiti con \edef.

        • #121474
          Up
          0
          Down
          ::

          mattiaca” post=122036Mi sto documentando un po’ sulle primitive tex per personalizzare qualche macro sopratutto quando utilizzo pgf e tikz per il disegno.
          Leggendo qua e là nella documentazione mi sono imbattuto nelle dichiarazioni in oggetto, ma sinceramente mi sfugge la loro differenza, cioè quando va utilizzata l’una o l’altra.
          Apparentemente \let copia il comando espandendolo proprio come fa edef, o mi sbaglio?
          Ecco un emc:
          `
          \documentclass{article}
          \begin{document}
          \def\a{aaa}
          \edef\b{\a}
          \let\c\a
          \def\d{\a}
          \a \space \b \space \c \space \d \par
          \def\a{ccc}
          \a \space \b \space \c \space \d \par
          \end{document}
          `

          Grazie a chi voglia rispondere a questa apparente banalità.

          Il comando [tt]\let[/tt] non espande nulla.

          Ogni token che abbia un significato corrisponde a una certa area di memoria. I token predefiniti (caratteri e primitive) occupano aree fisse. Quando si definisce una nuova sequenza di controllo (o un carattere attivo), TeX crea due cose: un’area di memoria e un puntatore a quest’area (sto un po’ riassumendo, per non essere troppo tecnico).

          Se si dà [tt]\let=[/tt], TeX semplicemente indirizza il puntatore [tt][/tt] all’area di memoria corrispondente a [tt][/tt]. Se il [tt][/tt] non è definito, non lo sarà nemmeno [tt][/tt].

          Invece [tt]\edef{…}[/tt] crea sia il puntatore sia l’area di memoria. Se [tt][/tt] è già definito, il puntatore è distrutto e ricreato.

          Vediamo un esempio:
          `
          \def\a{esempio}
          \def\b{\a}
          \let\c\b
          \edef\d{\b}
          `
          Ci sono differenze fra [tt]\c[/tt] and [tt]\d[/tt]? Sì, abissali. L’espansione di primo livello di [tt]\c[/tt] è [tt]\a[/tt], quella di [tt]\d[/tt] è [tt]esempio[/tt]: infatti
          `
          \ifx\c\d VERO\else FALSO\fi
          `
          darebbe [tt]FALSO[/tt].

          Mi pare sufficiente per dire che non sono la stessa cosa.

          Ciao
          Enrico

      Visualizzazione 1 filone di risposte
      • Devi essere connesso per rispondere a questo topic.

      Go to top