2010-12-03 16 views
34

Tengo una tarea que debe entregarse mañana y parece que no puedo hacer bien esta parte. Ver Me dieron un archivo de entrada con varios nombres, algunos de los cuales necesito omitir, con información adicional sobre cada uno. Estaba intentando usar ANDs y OR para omitir los nombres que no necesitaba y se me ocurrió esto.Problemas con AND y OR (COBOL)

IF DL-CLASS-STANDING = 'First Yr' OR 'Second Yr' AND 
GRAD-STAT-IN = ' ' OR 'X' 

Se deshizo de todas menos una persona, pero cuando traté de añadir otro conjunto de AND y OR que el programa comenzó a actuar como las estipulaciones donde ni siquiera existe.

¿Lo hice demasiado complejo para el compilador? ¿Hay alguna manera más fácil de omitir las cosas?

Respuesta

132

Trate de añadir algunos paréntesis para agrupar cosas lógicamente:

IF (DL-CLASS-STANDING = 'First Yr' OR 'Second Yr') AND (GRAD-STAT-IN = ' ' OR 'X')

23

Guau, ha pasado tanto tiempo que ni siquiera puedo recordar si esa sintaxis es válida o no :-) Es posible que desee analizar la expresión abreviada porque la expansión puede no ser lo que usted piensa cuando hay muchas cosas de cláusulas Mucho mejor para ser explícito.

Sin embargo, lo que haría es utilizar las variables de nivel 88 para hacerlo más legible - 88 s eran niveles especiales para permitir que las condiciones que se especifican en la división de los datos directamente en lugar de utilizar las condiciones explícitas en el código.

En otras palabras, ponga algo como esto en su división de datos (esto es de memoria ya que mi único compilador COBOL está en el mainframe en el trabajo y me voy hoy).

03 DL-CLASS-STANDING PIC X(20). 
    88 IS-FIRST-YEAR    VALUE 'First Yr'. 
    88 IS-SECOND-YEAR    VALUE 'Second Yr'. 
03 GRAD-STAT-IN  PIC X. 
    88 GRAD-STAT-UNKNOWN   VALUE ' '. 
    88 GRAD-STAT-NO    VALUE 'X'. 

continuación, puede utilizar las variables de nivel 88 en sus expresiones:

IF (IS-FIRST-YEAR OR IS-SECOND-YEAR) AND (GRAD-STAT-UNKNOWN OR GRAD-STAT-NO) ... 

Este es, en mi opinión, más legible y todo el punto de COBOL fue para parecerse a leer Inglés, después de todo .

+0

No soy un programador COBOL pero esto '88' sintaxis doesn No se parece en nada a un inglés legible para mí. – Asaph

+2

@Asaph, agregó el bit de código (legible) para todas las personas que no son de COBOL, todos 99.99999999999% de ustedes :-) – paxdiablo

+0

@paxdiablo: Gracias. Eso ayuda. Pero creo que me quedaré con Java. :) – Asaph

7

La primera cosa a tener en cuenta es que el código que se muestra es el código que estaba trabajando, el código modificado que no dio el resultado deseado se nunca se muestra Como una adición, ¿por qué, si solo quedara una persona, sería necesaria más selección? En resumen, la pregunta real no está clara más allá de decir "No sé cómo usar O en COBOL. No sé cómo usar Y en COBOL".

Más allá de eso, había dos preguntas reales:

  1. ¿Acaso os he demasiado complejo para el compilador?

  2. ¿Hay alguna manera más fácil de omitir las cosas [hay una manera más clara de escribir las condiciones]?

Para el primero, la respuesta es No, está muy lejos de ser difícil para el compilador. El compilador sabe exactamente cómo manejar cualquier combinación de O, Y (y NO, que veremos más adelante). El problema es si el escritor/lector humano puede codificar una condición de manera tal que el compilador sepa lo que quiere, en lugar de simplemente dar el resultado del compilador siguiendo sus reglas (que no tienen en cuenta las posibles interpretaciones humanas de una línea). de código)?Por lo tanto,

La segunda pregunta es:

¿Cómo escribo una condición compleja que el compilador va a entender de una manera idéntica a mi intención como autor y de forma idéntica para cualquier lector del código con un poco de experiencia de COBOL?

En primer lugar, una reordenación rápida del código (de trabajo) en la pregunta:

IF DL-CLASS-STANDING = 'First Yr' OR 'Second Yr' 
AND GRAD-STAT-IN = ' ' OR 'X' 

Y del código sugerido en una de las respuestas:

IF (DL-CLASS-STANDING = 'First Yr' OR 'Second Yr') 
AND (GRAD-STAT-IN = ' ' OR 'X') 

La segunda versión es más claro, pero (oy) es idéntico al primero. No hizo que el código funcionara, permitió que el código siguiera funcionando.

La respuesta abordaba la resolución del problema de una condición que aumentaba su complejidad: corchetes/paréntesis (simplificar la complejidad es otra posibilidad, pero sin el ejemplo que no funciona es difícil hacer sugerencias).

El código original funciona pero cuando tiene que ser más complejo, las ruedas comienzan a caerse.

El código sugerido funciona, pero no (totalmente) a resolver el problema de extender la complejidad de la condición, ya que, en si menor, se repite el problema, dentro del paréntesis, de extender la complejidad de la condición .

¿Cómo es esto?

Un simple condición:

IF A EQUAL TO "B" 

Una condición poco más compleja:

IF A EQUAL TO "B" OR "C" 

Un ligero, pero no completa, la simplificación de que:

IF (A EQUAL TO "B" OR "C") 

Si la condición tiene volverse más complejo, con AND, puede ser simple para los humanos (al compilador no le importa, no puede e engañado):

IF (A EQUAL TO "B" OR "C") 
AND (E EQUAL TO "F") 

¿Pero qué hay de esto?

IF (A EQUAL TO "B" OR "C" AND E EQUAL TO "F") 

Colocar el AND dentro de los soportes ha permitido que se replique el problema original para humanos. ¿Qué significa eso? ¿Cómo funciona?

Una respuesta es la siguiente:

IF (A EQUAL TO ("B" OR "C") AND E EQUAL TO "F") 

Tal vez más claro, pero no a todo el mundo, y de nuevo todavía existe el problema original, en el menor de edad.

Así:

IF A EQUAL TO "B" 
OR A EQUAL TO "C" 

simplificado, para la primera parte, pero aún así el problema en el menor de edad (apenas agregar y ...), Por lo que:

IF (A EQUAL TO "B") 
OR (A EQUAL TO "C") 

que conduce a:

IF ((A EQUAL TO "B") 
OR (A EQUAL TO "C")) 

Y:

IF ((A EQUAL TO "B") 
OR (A EQUAL TO C)) 

Ahora, si alguien quiere aumentar con Y, es fácil y clara. Si se hace en el mismo nivel que una de las partes de condición, solo se une a eso. Si se hace en el nivel más externo, se une a ambos (todos).

IF (((A EQUAL TO "B") 
    AND (E EQUAL TO "F")) 
OR (A EQUAL TO "C")) 

o

IF (((A EQUAL TO "B") 
OR (A EQUAL TO "C")) 
AND (E EQUAL TO "F")) 

¿Qué pasa si alguien quiere insertar la Y dentro de los corchetes? Bueno, porque dentro de los corchetes es simple, las personas no tienden a hacer eso. Si lo que está dentro de los corchetes ya es complicado, tiende a agregarse. Parece que algo que es simple por sí solo tiende a no complicarse, mientras que algo que ya es complicado (más de una cosa, no por sí mismo) tiende a hacerse más complejo sin pensarlo demasiado.

COBOL es un lenguaje antiguo. Man viejos programas escritos en COBOL todavía están en ejecución. Muchos programas COBOL tienen que ser enmendados, o simplemente leídos para comprender algo, muchas veces durante sus vidas de muchos años.

Al cambiar el código, al agregar algo a una condición, es mejor si las partes originales de la condición no necesitan ser "alteradas". Si la complejidad se deja entre corchetes, es más probable que el código deba ser alterado, lo que aumenta la cantidad de tiempo de comprensión (es más complejo) y cambiante (se necesita más atención, se necesitan más pruebas porque se altera el código). .

Muchos programas antiguos serán ejemplos de malas prácticas. No hay mucho que hacer al respecto, excepto tener cuidado con ellos.

No hay excusa para escribir un nuevo código que requiere más mantenimiento y cuidado en el futuro de lo que es absolutamente necesario.

Ahora, los ejemplos anteriores pueden considerarse largos. Es COBOL, ¿verdad? Un montón de tipeo? Pero COBOL ofrece una inmensa flexibilidad en la definición de datos. COBOL tiene, como parte de eso, el Nivel 88, el Nombre de la condición.

Éstos son definición de datos para una parte de los anteriores:

01 A PIC X. 
    88 PARCEL-IS-OUTSIZED VALUE "B" "C". 
01 F PIC X. 
    88 POSTAGE-IS-SUFFICIENT VALUE "F". 

La condición se convierte en:

IF PARCEL-IS-OUTSIZED 
AND POSTAGE-IS-SUFFICIENT 

En lugar de los valores simplemente literal, todos los valores literales correspondientes tienen ahora un nombre, de modo que el codificador puede indicar lo que realmente significan, así como los valores reales que tienen ese significado. Si se agregan más categorías a PARCEL-IS-OUTSIZED, se amplía la cláusula VALOR en el nivel 88.

Si se va a combinar otra condición, es mucho más simple hacerlo.

¿Es esto cierto? Bueno, sí. Míralo de esta manera.

COBOL opera en los resultados de una condición donde codificado.

If condition 

condiciones simples pueden ser agravados por el uso de soportes, para hacer una condición:

If condition = If (condition) = If ((condition1) operator (condition2))... 

Y así sucesivamente, hasta el límite del compilador.

El humano solo tiene que lidiar con la condición que desea para el propósito en cuestión. Para el flujo lógico general, observe la condición If, para verifique el detalle más bajo, para un subconjunto, observe la parte de la condición relevante para el subconjunto.

Use condiciones simples. Haga las condiciones simples a través de paréntesis/paréntesis. Realice condiciones complejas, donde sea necesario, combinando condiciones simples. Use nombres de condición para comparaciones con valores literales.

OY han sido tratados hasta el momento. NO se ve a menudo como algo para tratar con cautela:

IF NOT A EQUAL TO B 
IF A NOT EQUAL TO B 

IF (NOT (A EQUAL TO B)), remembering that this is just IF condition 

Así que NO no es aterrador, si se hace simple.

En todo momento, he estado editando espacios. Debido a que los corchetes están ahí, me gusta ponerlos en su cara. Me gusta estructurar y sangrar condiciones, para enfatizar el significado que les he dado.

Así:

IF (((condition1) 
    OR (condition2)) 
AND 
    ((condition3) 
    OR (condition4))) 

(y más esculpido que eso también). Al estructurar, espero que a) Me equivoque menos yb) cuando/si me equivoco, alguien tiene una mejor oportunidad de darse cuenta.

Si las condiciones no se simplifican, entender el código es más difícil. Cambiar el código es más difícil. Para las personas que aprenden COBOL, mantener las cosas simples es un beneficio a largo plazo para todos.

0

Como regla, evito el uso de AND si es posible. Los IF anidados funcionan igual de bien, son más fáciles de leer y con un uso juicioso de 88 niveles, no tienen que ir muy profundo. Esto parece mucho más fácil de leer, por lo menos en mi experiencia:

05 DL-CLASS-STANDING   PIC X(20) VALUE SPACE. 
    88 DL-CLASS-STANDING-VALID VALUE 'First Yr' 'Second Yr'. 
05 GRAD-STAT-IN     PIC X  VALUE SPACE. 
    88 GRAD-STAT-IN-VALID  VALUE SPACE 'N'. 

continuación, el código es tan simple como esto:

IF DL-CLASS-STANDING-VALID 
    IF GRAD-STAT-IN-VALID 
     ACTION ... .