close Warning: Can't synchronize with repository "(default)" (/var/svn/tolp does not appear to be a Subversion repository.). Look in the Trac log for more information.

Changes between Version 4 and Version 5 of NameBlock


Ignore:
Timestamp:
Feb 27, 2009, 11:19:05 AM (16 years ago)
Author:
Víctor de Buen Remiro
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • NameBlock

    v4 v5  
    99== Definiciones ==
    1010
    11         * Un bloque de nombres o NameBlock es un tipo de datos especial que se crea partiendo de un conjunto al que llamaremos base del NameBlock, y que implica un ámbito de localización de objetos.
    12         * A sus elementos les llamaremos miembros y pueden ser tanto variables como funciones o estructuras.
    13         * Los habrá que permanezcan ocultos fuera del ámbito y les llamaremos miembros privados.
    14         * El resto, llamados miembros públicos, podrán ser accesibles desde el exterior, a pesar de ser siempre todos locales por construcción, sin necesidad de explicitar las llaves {...}.
     11 * Un bloque de nombres o NameBlock es un tipo de datos especial que se crea partiendo de un conjunto al que llamaremos base del NameBlock, y que implica un ámbito de localización de objetos.
     12 * A sus elementos les llamaremos miembros y pueden ser tanto variables como funciones o estructuras.
     13 * Los habrá que permanezcan ocultos fuera del ámbito y les llamaremos miembros privados.
     14 * El resto, llamados miembros públicos, podrán ser accesibles desde el exterior, a pesar de ser siempre todos locales por construcción, sin necesidad de explicitar las llaves {...}.
    1515
    1616sintaxis
     
    2323=== 1. Reglas de declaración de un NameBlock ===
    2424
    25         * 1.1. La sintaxis de definición de un NameBlock admite únicamente tres posibles formas BNF, de las cuales se dan más detalles en los apartados posteriores:
    26               o 1.1.1.A partir de una expresión similar a la de un conjunto definido directamente con [[...]] :
    27 {{{
    28                 <nameblock_declaration> ::= "NameBlock" <variable_id> "="
    29                 "[["
    30                   [{
    31                     <public_member_expression> |
    32                     <private_member_expression> "," | ";" }]
    33                   <public_member_expression>
    34                   [{
    35                     "," | ";"
    36                     <public_member_expression> |
    37                     <private_member_expression> } ]
    38                 "]]"
    39 }}}
    40               o 1.1.2.Como alias de otro NameBlock
    41 {{{
    42                 <nameblock_declaration> ::= "NameBlock" <variable_id> "="
    43                   <member_expression>
    44 
    45                 <member_expression> ::=
    46                   <variable_id> |
    47                   <variable_id>"::"<public_member_expression>
    48 }}}
    49               o 1.1.3.Como resultado de una función que devuelva NameBlock anidado
    50 {{{
    51                 <nameblock_declaration> ::= "NameBlock" <variable_id> "="
    52                   <member_expression>
    53 
    54                 <member_expression> ::=
    55                   <variable_id> |
    56                   <variable_id>"::"<public_member_expression>
    57 }}}
    58         * 1.2. Declaración de miembros:
    59               o 1.2.1 El prefijo subrayador simple _ especifica los miembros privados de un NameBlock.
    60 {{{
    61                 <private_member_expression> ::=
    62                   <type_id> "_"<alphanumeric_char><variable_id>
    63                   ["=" <object_expression>]
    64 }}}
    65               o 1.2.2 El prefijo subrayador+punto _. se reserva para miembros de sólo lectura como por ejemplo _.autodoc.description. Estos miembros no son plenamente accesibles, por lo que son realmente un caso particular de miembro privado. Sin embargo, sí se puede obtener una copia de su contenido a través del operador :: lo cual impide su modificación por medios externos al NameBlock.
    66 {{{
    67                 <read-only_member_expression> ::=
    68                   <type_id> "_"<alphanumeric_char><.variable_id>
    69                   ["=" <object_expression>]
    70 }}}
    71               o 1.2.3. Un NameBlock puede o no tener miembros privados pero ha de tener al menos un miembro público, con excepción del NameBlock Unknown del sistema que es el vacío.
    72 {{{
    73                 <public_member_expression> ::=
    74                   <type_id>   <alphanumeric_char><variable_id>
    75                   ["=" <object_expression>]
    76 }}}
    77                 Ejemplo de uso inválido:
    78 {{{
    79                 NameBlock BadNS_1.2.3.a = Unknown;
    80                 NameBlock BadNS_1.2.3.b = [[Real _a=0]];
    81 }}}
    82           Veámoslo con un ejemplo:
    83 {{{
    84           NameBlock MyNS_1.2 = 
    85           [[
    86             Text _.autodoc.description = "NameBlock de ejemplo del punto 1.2";
    87           //Public members
    88             Struct mystr { Real x_; Text t_ };
    89             Set real2mystr(Real x)
    90             {
    91               mystr(x,""+FormatReal(x,"%.15lg"))
    92             };
    93           //Private member
    94             Real _fun_aux(Real x) { x*4 };
    95           //Public members
    96             Real fun_a(Real x) { _fun_aux(x)+1 };
    97             Real fun_b(Real x) { _fun_aux(x)-1 };
    98           //Private members
    99             Real _aux_1 = 1;
    100             Real _aux_2 = 2;
    101             Set  _aux_3 = real2mystr(2);
    102           //Read only members
    103             Real _.exported_1 = _aux_1+_aux_2;
    104             Real _.exported_2 = _aux_1-_aux_2*_aux_3->x_
    105           ]];
    106 }}}
    107         * 1.3. Restricciones sobre la creación de miembros
    108               o 1.3.1 Un NameBlock no puede tener varios miembros con el mismo nombre. Ejemplo de uso inválido:
    109 {{{
    110                 NameBlock BadNS_1.3.1 =
    111                 [[
    112                   Set _a = { [[Real x=0]] };
    113                   Set _b = { [[Real x=1]] };
    114                   _a[1],
    115                   _b[1]
    116                 ]]
    117 }}}
    118               o 1.3.2. Un NameBlock no puede tener miembros sin nombre. Ejemplo de uso inválido:
    119 {{{
    120                 NameBlock BadNS_1.3.2 = [[Real 0]];
    121 }}}
    122               o 1.3.4. Un NameBlock no puede tener sólo sentencias que no devuelvan una variable, una función o una estructura, como por ejemplo el Write, o el While. Ejemplo de uso inválido:
    123 {{{
    124                 NameBlock BadNS_1.3.4 =
    125                 [[
    126                   WriteLn("Hola")
    127                 ]];
    128 }}}
    129               o 1.3.5. Un NameBlock no puede tener miembros que sean globales o accesibles al mismo nivel que el propio NameBlock o a nivel superior. Ejemplo de uso inválido:
    130 {{{
    131                 Real x=0;
    132                 NameBlock BadNS_1.3.5 = [[Real x]];
     25 * 1.1. La sintaxis de definición de un NameBlock admite únicamente tres posibles formas BNF, de las cuales se dan más detalles en los apartados posteriores:
     26  * 1.1.1.A partir de una expresión similar a la de un conjunto definido directamente con [[...]] :
     27{{{
     28  <nameblock_declaration> ::= "NameBlock" <variable_id> "="
     29  "[["
     30    [{
     31      <public_member_expression> |
     32      <private_member_expression> "," | ";" }]
     33    <public_member_expression>
     34    [{
     35      "," | ";"
     36      <public_member_expression> |
     37      <private_member_expression> } ]
     38  "]]"
     39}}}
     40  * 1.1.2.Como alias de otro NameBlock
     41{{{
     42  <nameblock_declaration> ::= "NameBlock" <variable_id> "="
     43    <member_expression>
     44
     45  <member_expression> ::=
     46    <variable_id> |
     47    <variable_id>"::"<public_member_expression>
     48}}}
     49  * 1.1.3.Como resultado de una función que devuelva NameBlock anidado
     50{{{
     51  <nameblock_declaration> ::= "NameBlock" <variable_id> "="
     52    <member_expression>
     53
     54  <member_expression> ::=
     55    <variable_id> |
     56    <variable_id>"::"<public_member_expression>
     57}}}
     58 * 1.2. Declaración de miembros:
     59  * 1.2.1 El prefijo subrayador simple _ especifica los miembros privados de un NameBlock.
     60{{{
     61  <private_member_expression> ::=
     62    <type_id> "_"<alphanumeric_char><variable_id>
     63    ["=" <object_expression>]
     64}}}
     65  * 1.2.2 El prefijo subrayador+punto _. se reserva para miembros de sólo lectura como por ejemplo _.autodoc.description. Estos miembros no son plenamente accesibles, por lo que son realmente un caso particular de miembro privado. Sin embargo, sí se puede obtener una copia de su contenido a través del operador :: lo cual impide su modificación por medios externos al NameBlock.
     66{{{
     67  <read-only_member_expression> ::=
     68    <type_id> "_"<alphanumeric_char><.variable_id>
     69    ["=" <object_expression>]
     70}}}
     71  * 1.2.3. Un NameBlock puede o no tener miembros privados pero ha de tener al menos un miembro público, con excepción del NameBlock Unknown del sistema que es el vacío.
     72{{{
     73  <public_member_expression> ::=
     74    <type_id>   <alphanumeric_char><variable_id>
     75    ["=" <object_expression>]
     76}}}
     77  Ejemplo de uso inválido:
     78{{{
     79  NameBlock BadNS_1.2.3.a = Unknown;
     80  NameBlock BadNS_1.2.3.b = [[Real _a=0]];
     81}}}
     82  Veámoslo con un ejemplo:
     83{{{
     84  NameBlock MyNS_1.2 = 
     85  [[
     86    Text _.autodoc.description = "NameBlock de ejemplo del punto 1.2";
     87  //Public members
     88    Struct mystr { Real x_; Text t_ };
     89    Set real2mystr(Real x)
     90    {
     91      mystr(x,""+FormatReal(x,"%.15lg"))
     92    };
     93  //Private member
     94    Real _fun_aux(Real x) { x*4 };
     95  //Public members
     96    Real fun_a(Real x) { _fun_aux(x)+1 };
     97    Real fun_b(Real x) { _fun_aux(x)-1 };
     98  //Private members
     99    Real _aux_1 = 1;
     100    Real _aux_2 = 2;
     101    Set  _aux_3 = real2mystr(2);
     102  //Read only members
     103    Real _.exported_1 = _aux_1+_aux_2;
     104    Real _.exported_2 = _aux_1-_aux_2*_aux_3->x_
     105  ]];
     106}}}
     107 * 1.3. Restricciones sobre la creación de miembros
     108  * 1.3.1 Un NameBlock no puede tener varios miembros con el mismo nombre. Ejemplo de uso inválido:
     109{{{
     110  NameBlock BadNS_1.3.1 =
     111  [[
     112    Set _a = { [[Real x=0]] };
     113    Set _b = { [[Real x=1]] };
     114    _a[1],
     115    _b[1]
     116  ]]
     117}}}
     118  * 1.3.2. Un NameBlock no puede tener miembros sin nombre. Ejemplo de uso inválido:
     119{{{
     120  NameBlock BadNS_1.3.2 = [[Real 0]];
     121}}}
     122  * 1.3.4. Un NameBlock no puede tener sólo sentencias que no devuelvan una variable, una función o una estructura, como por ejemplo el Write, o el While. Ejemplo de uso inválido:
     123{{{
     124  NameBlock BadNS_1.3.4 =
     125  [[
     126    WriteLn("Hola")
     127  ]];
     128}}}
     129  * 1.3.5. Un NameBlock no puede tener miembros que sean globales o accesibles al mismo nivel que el propio NameBlock o a nivel superior. Ejemplo de uso inválido:
     130{{{
     131  Real x=0;
     132  NameBlock BadNS_1.3.5 = [[Real x]];
    133133}}}
    134134
    135135=== 2. Reglas de acceso a miembros ===
    136136
    137         * 2.1. Para acceder a los miembros públicos se usará el nombre del NameBlock con el operador especial
    138 
    139           
    140           Anything nameblock_id::public_member_id
    141 
    142           Siguiendo con el ejemplo del punto 1.2 anterior:
    143 {{{
    144           Real MyNS_1.2::_.exported_1;
    145           Real MyNS_1.2::_.exported_2;
    146           Real MyNS_1.2::fun_a(MyNS_1.2::_.exported_1);
    147           Set table =
    148           [[
    149             MyNS_1.2::mystr(1,"uno"),
    150             MyNS_1.2::real2mystr(4.0),
    151             MyNS_1.2::real2mystr(Pi)
    152           ]];
    153 }}}
    154   * 2.2. Evidentemente no se puede acceder con :: a los miembros privados. Ejemplo de uso inválido:
    155 {{{
    156     Real MyNS_1.2::_aux_1; 
    157     Real MyNS_1.2::_fun_aux(1);
     137 * 2.1. Para acceder a los miembros públicos se usará el nombre del NameBlock con el operador especial
     138
     139   
     140  Anything nameblock_id::public_member_id
     141
     142  Siguiendo con el ejemplo del punto 1.2 anterior:
     143{{{
     144  Real MyNS_1.2::_.exported_1;
     145  Real MyNS_1.2::_.exported_2;
     146  Real MyNS_1.2::fun_a(MyNS_1.2::_.exported_1);
     147  Set table =
     148  [[
     149    MyNS_1.2::mystr(1,"uno"),
     150    MyNS_1.2::real2mystr(4.0),
     151    MyNS_1.2::real2mystr(Pi)
     152  ]];
     153}}}
     154 * 2.2. Evidentemente no se puede acceder con :: a los miembros privados. Ejemplo de uso inválido:
     155{{{
     156  Real MyNS_1.2::_aux_1; 
     157  Real MyNS_1.2::_fun_aux(1);
    158158}}}
    159159  * 2.3. En ningún caso es posible acceder a los miembros públicos ni privados de un NameBlock mediante los operadores de acceso a Set Set[Real], Set[Text],y aún menos con Set->field_name puesto que no puede existir un NameSpace con estructura. Ejemplo de uso inválido:
    160160{{{
    161     Real MyNS_1.2[3];
    162     Real MyNS_1.2["exported_2"];
    163     Real BadNS_2.3->x_;
     161  Real MyNS_1.2[3];
     162  Real MyNS_1.2["exported_2"];
     163  Real BadNS_2.3->x_;
    164164}}}
    165165  * 2.4. Nótese que el concepto de miembro se extiende tan sólo a los elementos a primer nivel del conjunto base de un NameBlock, y no al resto de elementos de su jerarquía recursiva de subconjuntos aunque tengan nombre accesible desde el nivel del conjunto.
     
    175175=== 3. Reglas de anidación ===
    176176
    177         * 3.1. Para poder acceder de modo recursivo a los NameBlock's, estos pueden estar anidados como en este nuevo. Ejemplo:
    178 {{{
    179           NameBlock MyNS_3.1 =
    180           [[
    181             NameBlock a = [[ Real a1 = 1; Real a2 = 2 ]]
    182           ]];
    183           Real MyNS_3.1::a::a1; 
    184 }}}
    185         * 3.2. Un modo especialmente práctico que puede ayudar a la organización del código sería usar el Include como en el siguiente ejemplo 3.2
    186 {{{
    187           //Fichero ns1.tol
    188           ...
    189 
    190           NameBlock NS1 = [[
    191           Real _aux_1 = 1;
    192           Real _aux_2 = 2;
    193           Real a = _aux_1+_aux_2;
    194           Real b = _aux_1-_aux_2
    195           ]];
    196           ...
    197 
    198           //Fichero ns2.tol
    199           ...
    200           NameBlock NS2 = [[
    201           Real _fun_aux(Real x) { x*4 };
    202           Real fun_a(Real x) { _fun_aux(x)+1 };
    203           Real fun_b(Real x) { _fun_aux(x)-1 }
    204           ]];
    205           ...
    206 
    207           //Fichero MyNS_3.2.tol
    208           NameBlock MyNS_3.2 =
    209           [[
    210           //Private:
    211             Set _ns1 = Include("ns1.tol");
    212             Set _ns2 = Include("ns2.tol");
    213           //Public:
    214             NameBlock NS1;
    215             NameBlock NS2
    216           ]];
    217 }}}
    218           Obsérvese que sólo se publican NS1y NS2 por lo que cualquier cosa definida en ns1.tol y ns2.tol distinta de ellos permanecerá inaccesible externamente.
    219         * 3.3. Para mayor comodidad se puede renombrar externamente un NameBlock anidado con un alias identificativo más corto que la concatenación completa de NameBlock's, como se ha visto en el punto 1.1.3. Esto evita tener que escribir demasiados nombres largos que dificulten la lectura. Pero se debe usar siempre de forma cuidadosa, cuando no dé lugar a ambigüedades y siempre en código de usuario final, nunca en librerías de funciones de uso general, pues en tal caso destruye los principios de organización y modularidad que es uno de los principales objetivos de NameBlock.
    220 
    221           En un programa concreto de usuario que va a hacer uso intensivo de un NameBlock de nombre muy largo se podría considear razonable crear un alias como por ejemplo:
    222 {{{
    223           NameBlock _aia = std::math::stat::model::mle::arima::aia;
     177 * 3.1. Para poder acceder de modo recursivo a los NameBlock's, estos pueden estar anidados como en este nuevo. Ejemplo:
     178{{{
     179  NameBlock MyNS_3.1 =
     180  [[
     181    NameBlock a = [[ Real a1 = 1; Real a2 = 2 ]]
     182  ]];
     183  Real MyNS_3.1::a::a1; 
     184}}}
     185 * 3.2. Un modo especialmente práctico que puede ayudar a la organización del código sería usar el Include como en el siguiente ejemplo 3.2
     186{{{
     187  //Fichero ns1.tol
     188  ...
     189
     190  NameBlock NS1 = [[
     191  Real _aux_1 = 1;
     192  Real _aux_2 = 2;
     193  Real a = _aux_1+_aux_2;
     194  Real b = _aux_1-_aux_2
     195  ]];
     196  ...
     197
     198  //Fichero ns2.tol
     199  ...
     200  NameBlock NS2 = [[
     201  Real _fun_aux(Real x) { x*4 };
     202  Real fun_a(Real x) { _fun_aux(x)+1 };
     203  Real fun_b(Real x) { _fun_aux(x)-1 }
     204  ]];
     205  ...
     206
     207  //Fichero MyNS_3.2.tol
     208  NameBlock MyNS_3.2 =
     209  [[
     210  //Private:
     211    Set _ns1 = Include("ns1.tol");
     212    Set _ns2 = Include("ns2.tol");
     213  //Public:
     214    NameBlock NS1;
     215    NameBlock NS2
     216  ]];
     217}}}
     218  Obsérvese que sólo se publican NS1y NS2 por lo que cualquier cosa definida en ns1.tol y ns2.tol distinta de ellos permanecerá inaccesible externamente.
     219 * 3.3. Para mayor comodidad se puede renombrar externamente un NameBlock anidado con un alias identificativo más corto que la concatenación completa de NameBlock's, como se ha visto en el punto 1.1.3. Esto evita tener que escribir demasiados nombres largos que dificulten la lectura. Pero se debe usar siempre de forma cuidadosa, cuando no dé lugar a ambigüedades y siempre en código de usuario final, nunca en librerías de funciones de uso general, pues en tal caso destruye los principios de organización y modularidad que es uno de los principales objetivos de NameBlock.
     220
     221  En un programa concreto de usuario que va a hacer uso intensivo de un NameBlock de nombre muy largo se podría considear razonable crear un alias como por ejemplo:
     222{{{
     223  NameBlock _aia = std::math::stat::model::mle::arima::aia;
    224224}}}
    225225
    226226=== 4. Reglas de publicación o globalización ===
    227227
    228         * 4.1.En determinadas circunstancias los miembros públicos o de sólo lectura de un NameBlock pueden pasar al ámbito global, es decir, se puede acceder a ellos sin explicitarlo con ::. A este hecho se le llamará publicar un NameBlock y se logra con el operador Real UsingNameBlock(NameBlock nameblock_idt) y es similar al using namespace de C++, aunque con ciertas diferencias.
    229         * 4.2.El operador UsingNameBlock devuelve cierto si es compatible con el resto de variables de tipo NameBlock actualmente globalizadas, es decir, si no contiene ningún miembro público con el mismo nombre que otro. Los miembros que ya estuvieran presentes no serán accesibles de forma implícita pero sí mediante ::, y se mostrará un mensaje de aviso para advertirlo.
    230         * 4.3.Como es lógico, este operador de globalización no surte efecto si se llama en ambiente local, lo cual incluye dentro de un NameBlock, y devolverá falso y un mensaje de error si se intenta.
    231         * 4.4.El NameBlock permanecerá en uso mientras siga existiendo el objeto devuelto por este operador. Por ejemplo, si se ha incluido en un fichero estará presente hasta que se descompile dicho fichero.
    232         * 4.5.Si existe una variable global previa con el mismo nombre ocultará el miembro NameBlock publicado que seguirá siendo accesible con ::, como es lógico. Si se crea la variable global posteriormente se actuará del mismo modo.
    233         * 4.6.Se trata de una sentencia no declarativa sino ejecutiva por lo que no tiene efecto si se recupera de un módulo OIS.
    234         * 4.7.Al igual que con los alias del apartado 3.3., se debe ser sumamente cauteloso con este tipo de sentencias y no incluirlas en librerías de caracter general. Sería prudente usarlas sólo en programas de usuario final y cuando no haya ninguna posible ambigüedad de nomenclatura. Puede ser particularmente útil para mantener compatibilidad hacia atrás de código creado previamente a la existencia de NameBlock.
     228 * 4.1.En determinadas circunstancias los miembros públicos o de sólo lectura de un NameBlock pueden pasar al ámbito global, es decir, se puede acceder a ellos sin explicitarlo con ::. A este hecho se le llamará publicar un NameBlock y se logra con el operador Real UsingNameBlock(NameBlock nameblock_idt) y es similar al using namespace de C++, aunque con ciertas diferencias.
     229 * 4.2.El operador UsingNameBlock devuelve cierto si es compatible con el resto de variables de tipo NameBlock actualmente globalizadas, es decir, si no contiene ningún miembro público con el mismo nombre que otro. Los miembros que ya estuvieran presentes no serán accesibles de forma implícita pero sí mediante ::, y se mostrará un mensaje de aviso para advertirlo.
     230 * 4.3.Como es lógico, este operador de globalización no surte efecto si se llama en ambiente local, lo cual incluye dentro de un NameBlock, y devolverá falso y un mensaje de error si se intenta.
     231 * 4.4.El NameBlock permanecerá en uso mientras siga existiendo el objeto devuelto por este operador. Por ejemplo, si se ha incluido en un fichero estará presente hasta que se descompile dicho fichero.
     232 * 4.5.Si existe una variable global previa con el mismo nombre ocultará el miembro NameBlock publicado que seguirá siendo accesible con ::, como es lógico. Si se crea la variable global posteriormente se actuará del mismo modo.
     233 * 4.6.Se trata de una sentencia no declarativa sino ejecutiva por lo que no tiene efecto si se recupera de un módulo OIS.
     234 * 4.7.Al igual que con los alias del apartado 3.3., se debe ser sumamente cauteloso con este tipo de sentencias y no incluirlas en librerías de caracter general. Sería prudente usarlas sólo en programas de usuario final y cuando no haya ninguna posible ambigüedad de nomenclatura. Puede ser particularmente útil para mantener compatibilidad hacia atrás de código creado previamente a la existencia de NameBlock.
    235235
    236236=== 5. Reglas de ámbito ===
    237237    Un NameBlock tiene su propia tabla de símbolos que se usa cuando está activo, es decir, cuando se está ejecutando alguna de sus funciones miembro. Sólo puede haber activo un NameBlock al mismo tiempo o bien no haber ninguno activo en cuyo caso todo funciona como hasta ahora. El orden de búsquedas de símbolos de TOL que anteriormente se reducía a símbolos de ámbito local y ámbito global, pasa a ser el siguiente:
    238238
    239         * 5.1. Miembro local: Si hay un NameBlock activo se busca ahí.
    240         * 5.2. Ámbito local: Si no lo había o bien no contiene el nombre buscado y estamos en ambiente local se busca en la pila local.
    241         * 5.3. Ámbito global: Si aún no se ha encontrado nada en los dos puntos anteriores se busca en la tabla global de símbolos.
    242         * 5.4. Miembro publicado: Si sigue sin encontrarse el símbolo se buscará en la tabla de NameBlock publicados.
    243 
    244     Cuando se llama a una función de un NameBlock se activa el mismo y la búsqueda de variables, funciones y estructuras locales le da total prioridad a los miembros de ese NameBlock de forma que se pueden usar todos ellos, tanto públicos como privados.
    245 
    246     Esto reduce el uso actual de scope dinámico en la pila local de llamadas de funciones, lo cual puede ayudar a medio plazo a reconducir a los usuarios de TOL a los estándares de programación.
     239 * 5.1. Miembro local: Si hay un NameBlock activo se busca ahí.
     240 * 5.2. Ámbito local: Si no lo había o bien no contiene el nombre buscado y estamos en ambiente local se busca en la pila local.
     241 * 5.3. Ámbito global: Si aún no se ha encontrado nada en los dos puntos anteriores se busca en la tabla global de símbolos.
     242 * 5.4. Miembro publicado: Si sigue sin encontrarse el símbolo se buscará en la tabla de NameBlock publicados.
     243
     244  Cuando se llama a una función de un NameBlock se activa el mismo y la búsqueda de variables, funciones y estructuras locales le da total prioridad a los miembros de ese NameBlock de forma que se pueden usar todos ellos, tanto públicos como privados.
     245
     246  Esto reduce el uso actual de scope dinámico en la pila local de llamadas de funciones, lo cual puede ayudar a medio plazo a reconducir a los usuarios de TOL a los estándares de programación.
    247247
    248248== Ventajas ==
     
    252252=== Modularidad ===
    253253
    254     La principal utilidad del NameBlock es dotar a TOL de un mecanismo de modularidad más allá del fichero que permita construir módulos, paquetes y librerías robustamente organizados. Una forma prudente de anidar los NameBlock's sería en este caso: lib_id::package_id::module_id
     254  La principal utilidad del NameBlock es dotar a TOL de un mecanismo de modularidad más allá del fichero que permita construir módulos, paquetes y librerías robustamente organizados. Una forma prudente de anidar los NameBlock's sería en este caso: lib_id::package_id::module_id
    255255Legibilidad
    256     Pero un NameBlock podría también ayudar a la legibilidad del código en tareas más humildes, al sustituir llamadas a set[num_field] por set::name_field sin el coste computacional añadido de set["name_field"] y sin tener que definir estructuras de datos espúreas para usar set->name_field
     256  Pero un NameBlock podría también ayudar a la legibilidad del código en tareas más humildes, al sustituir llamadas a set[num_field] por set::name_field sin el coste computacional añadido de set["name_field"] y sin tener que definir estructuras de datos espúreas para usar set->name_field
    257257Eliminación de variables globales
    258     Un caso especialmente recomendable es el que afecta a todos los parámetros de configuración y variables globales en general que deberían incluirse dentro de un único NameBlock global para evitar colisiones de nombres.
    259 
    260     //Parámetros de configuración del proyecto
    261     NameBlock cfg =
    262     [[
    263     //Configuración del acceso a la base de datos
    264       NameBlock db   = [[Text alias, Text user, Text pwd, Text host, ...]],
    265     //Configuración de los directorios más utilizados
    266       NameBlock path = [[Text source, Text data, Text log, ...]],
    267       ...
    268     ]];
    269     Real DBOpen(cfg::db::alias, cfg::db::user, cfg::db::pwd);
     258  Un caso especialmente recomendable es el que afecta a todos los parámetros de configuración y variables globales en general que deberían incluirse dentro de un único NameBlock global para evitar colisiones de nombres.
     259
     260  //Parámetros de configuración del proyecto
     261  NameBlock cfg =
     262  [[
     263  //Configuración del acceso a la base de datos
     264    NameBlock db   = [[Text alias, Text user, Text pwd, Text host, ...]],
     265  //Configuración de los directorios más utilizados
     266    NameBlock path = [[Text source, Text data, Text log, ...]],
     267    ...
     268  ]];
     269  Real DBOpen(cfg::db::alias, cfg::db::user, cfg::db::pwd);
    270270
    271271=== Flexibilidad ===
    272272
    273     Las funciones que devuelven conjuntos heterogéneos también ganarían flexibilidad, expresibilidad y facilidad de mantenimiento y uso sin recurrir a la definición de estructuras locales
    274 
    275     NameBlock my_stats(Serie ser)
    276     {[[
    277       Real num  = CountS (ser);
    278       Real avg  = AvrS(ser);
    279       Real stdv = StDsS(ser)   
    280     ]]};
    281 
    282     NameBlock stats = my_stats(SubSer(Gaussian(0,1,C),y2000,y2000m12d31));
    283     Real stats::stdv;
    284 
    285     Aunque se añadan elementos a lo que devuelve la función o se reordenen los mismos seguirá funcionando el código que usara esta función accediendo con :: mientras no se cambien los nombres:
    286 
    287     NameBlock my_stats(Serie ser)
    288     {[[
    289       Real num  = CountS (ser);
    290       Real avg  = AvrS(ser);
    291       Real mdn  = MedianS(ser);
    292       Real stdv = StDsS(ser)   
    293     ]]};
     273  Las funciones que devuelven conjuntos heterogéneos también ganarían flexibilidad, expresibilidad y facilidad de mantenimiento y uso sin recurrir a la definición de estructuras locales
     274
     275  NameBlock my_stats(Serie ser)
     276  {[[
     277    Real num  = CountS (ser);
     278    Real avg  = AvrS(ser);
     279    Real stdv = StDsS(ser)   
     280  ]]};
     281
     282  NameBlock stats = my_stats(SubSer(Gaussian(0,1,C),y2000,y2000m12d31));
     283  Real stats::stdv;
     284
     285  Aunque se añadan elementos a lo que devuelve la función o se reordenen los mismos seguirá funcionando el código que usara esta función accediendo con :: mientras no se cambien los nombres:
     286
     287  NameBlock my_stats(Serie ser)
     288  {[[
     289    Real num  = CountS (ser);
     290    Real avg  = AvrS(ser);
     291    Real mdn  = MedianS(ser);
     292    Real stdv = StDsS(ser) 
     293  ]]};
    294294
    295295=== Generación automática de documentación ===
    296     A efectos de generación automática de documentación de un NameBlock, se cuenta con la función Set Members(NameBlock root) que devuelve un listado de los miembros públicos contenidos en un NameBlock y sus hijos de forma recursiva, con un registro para cada uno con la siguiente estructura informativa ordenada de la forma natural indicada por los propios campos:
    297 {{{
    298     Struct NameBlockInfoStruct
    299     {
    300       Text nameBlock_,   //full name block path a::b::...
    301       Text mode_,        //"Variable", "Function" or "Struct"
    302       Text grammar_,     //"Real", "Text", "Set", "NameBlock", ...
    303       Text memberName_,  //Internal public member name
    304       Text filePath_,    //Relative path to the root file path
    305       Text description_  //User description
    306     };
     296  A efectos de generación automática de documentación de un NameBlock, se cuenta con la función Set Members(NameBlock root) que devuelve un listado de los miembros públicos contenidos en un NameBlock y sus hijos de forma recursiva, con un registro para cada uno con la siguiente estructura informativa ordenada de la forma natural indicada por los propios campos:
     297{{{
     298  Struct NameBlockInfoStruct
     299  {
     300    Text nameBlock_,   //full name block path a::b::...
     301    Text mode_,    //"Variable", "Function" or "Struct"
     302    Text grammar_,   //"Real", "Text", "Set", "NameBlock", ...
     303    Text memberName_,  //Internal public member name
     304    Text filePath_,  //Relative path to the root file path
     305    Text description_  //User description
     306  };
    307307}}}
    308308==== Miembros de documentación accesibles de sólo lectura ====
    309     Son miembros de sólo lectura de la forma _.autodoc.<sufix>
    310 
    311         * _.autodoc.description: Si un NameBlock contiene un miembro privado Text _.autodoc.description, entonces su contenido pasa a ser la descripción del NameBlock sin necesidad de usar la función PutDescription.
    312         * _.autodoc.keys: Si un NameBlock contiene un miembro privado Set _.autodoc.keys, entonces sus elementos, que han de ser todos de tipo Text, pasan a ser palabras claves utilizadas en los procedimientos de búsqueda temática.
    313         * _.autodoc.url: Si un NameBlock contiene un miembro privado Text _.autodoc.url este se usará en los mecanismos de generación automática para enlazar a la URL especificada en la que se explicará de forma más detallada el funcionamiento del NameBlock.
    314         * _.autodoc.authors: Si un NameBlock contiene un miembro privado Set _.autodoc.authors este se usará en los mecanismos de generación automática para identificar a los autores del código.
     309  Son miembros de sólo lectura de la forma _.autodoc.<sufix>
     310
     311 * _.autodoc.description: Si un NameBlock contiene un miembro privado Text _.autodoc.description, entonces su contenido pasa a ser la descripción del NameBlock sin necesidad de usar la función PutDescription.
     312 * _.autodoc.keys: Si un NameBlock contiene un miembro privado Set _.autodoc.keys, entonces sus elementos, que han de ser todos de tipo Text, pasan a ser palabras claves utilizadas en los procedimientos de búsqueda temática.
     313 * _.autodoc.url: Si un NameBlock contiene un miembro privado Text _.autodoc.url este se usará en los mecanismos de generación automática para enlazar a la URL especificada en la que se explicará de forma más detallada el funcionamiento del NameBlock.
     314 * _.autodoc.authors: Si un NameBlock contiene un miembro privado Set _.autodoc.authors este se usará en los mecanismos de generación automática para identificar a los autores del código.
    315315
    316316==== Funciones de información relacionadas ====
    317317
    318         * Text GetNameBlock(Anything obj): Devuelve el nombre completo del NameBlock al que pertenece un objeto. Si no pertenece a ninguno devuelve la cadena vacía "".
    319         * Text FullName(Anything obj): Devuelve el nombre completo de un objeto, incluyendo el prefijo de su NameBlock si está dentro de uno.
     318 * Text GetNameBlock(Anything obj): Devuelve el nombre completo del NameBlock al que pertenece un objeto. Si no pertenece a ninguno devuelve la cadena vacía "".
     319 * Text FullName(Anything obj): Devuelve el nombre completo de un objeto, incluyendo el prefijo de su NameBlock si está dentro de uno.
    320320
    321321