CONTENIDO
- NOMBRE
- DESCRIPCIÓN
- Precedencia y asociatividad del operador
- Términos y operadores de lista (hacia la izquierda)
- El operador de flecha
- Auto-incremento y auto-decremento
- Exponenciación
- Operadores unarios simbólicos
- Operadores vinculantes
- Operadores multiplicativos
- Operadores aditivos
- Operadores de turnos
- Operadores unarios nombrados
- Operadores relacionales
- Operadores de igualdad
- Operador de instancia de clase
- Operador de Smartmatch
- Coincidencia inteligente de objetos
- Bit a bit y
- O bit a bit y O exclusivo
- Lógico estilo C y
- O lógico de estilo C
- Definido lógico-Or
- Operadores de rango
- Operador condicional
- Operadores de Asignación
- Operador de coma
- Operadores de lista (hacia la derecha)
- Lógico no
- Lógico y
- O lógico y exclusivo O
- C Operadores que faltan en Perl
- Operadores de cotizaciones y cotizaciones
- Operadores tipo cotización Regexp
- Operadores similares a cotizaciones
- Detalles sangrientos del análisis sintáctico de construcciones entre comillas
- Operadores de E / S
- Plegado constante
- Sin operaciones
- Operadores de cadena bit a bit
- Aritmética de enteros
- Aritmética de coma flotante
- Números más grandes
NOMBRE
perlop – Operadores de Perl y precedencia
DESCRIPCIÓN
En Perl, el operador determina qué operación se realiza, independientemente del tipo de operandos. Por ejemplo $x + $y
es siempre una suma numérica, y si $x
o $y
no contienen números, se intenta convertirlos primero en números.
Esto contrasta con muchos otros lenguajes dinámicos, donde la operación está determinada por el tipo del primer argumento. También significa que Perl tiene dos versiones de algunos operadores, una para la comparación numérica y otra para la comparación de cadenas. Por ejemplo $x == $y
compara dos números para la igualdad, y $x eq $y
compara dos cadenas.
Sin embargo, existen algunas excepciones: x
puede ser repetición de cadena o repetición de lista, dependiendo del tipo de operando izquierdo, y &
, |
, ^
y ~
pueden ser operaciones de cadena o de bits numéricos.
Precedencia y asociatividad del operador
La precedencia de operadores y la asociatividad funcionan en Perl más o menos como lo hacen en matemáticas.
Precedencia del operador significa que algunos operadores se agrupan más estrechamente que otros. Por ejemplo, en 2 + 4 * 5
, la multiplicación tiene mayor precedencia, por lo que 4 * 5
se agrupa como el operando de la derecha de la suma, en lugar de 2 + 4
agruparse como el operando de la izquierda de la multiplicación. Es como si la expresión estuviera escrita 2 + (4 * 5)
, no (2 + 4) * 5
. Entonces la expresión cede 2 + 20 == 22
, en vez de 6 * 5 == 30
.
Asociatividad del operador define lo que sucede si se usa una secuencia de los mismos operadores uno tras otro: por lo general, se agruparán a la izquierda oa la derecha. Por ejemplo, en 9 - 3 - 2
, la resta es asociativa por la izquierda, por lo que 9 - 3
se agrupa como el operando de la izquierda de la segunda resta, en lugar de 3 - 2
agruparse como el operando de la derecha de la primera resta. Es como si la expresión estuviera escrita (9 - 3) - 2
, no 9 - (3 - 2)
. Entonces la expresión cede 6 - 2 == 4
, en vez de 9 - 1 == 8
.
Para los operadores simples que evalúan todos sus operandos y luego combinan los valores de alguna manera, la precedencia y la asociatividad (y paréntesis) implican algunos requisitos de orden en las operaciones de combinación. Por ejemplo, en 2 + 4 * 5
, la agrupación implícita por precedencia significa que la multiplicación de 4 y 5 debe realizarse antes de la suma de 2 y 20, simplemente porque el resultado de esa multiplicación se requiere como uno de los operandos de la suma. Pero el orden de las operaciones no está completamente determinado por esto: en 2 * 2 + 4 * 5
Ambas multiplicaciones deben realizarse antes de la suma, pero la agrupación no dice nada sobre el orden en que se realizan las dos multiplicaciones. De hecho, Perl tiene una regla general de que los operandos de un operador se evalúan en orden de izquierda a derecha. Algunos operadores como &&=
tener reglas de evaluación especiales que pueden hacer que un operando no se evalúe en absoluto; en general, el operador de nivel superior en una expresión tiene el control de la evaluación del operando.
Algunos operadores de comparación, como su asociatividad, cadena con algunos operadores de la misma precedencia (pero nunca con operadores de diferente precedencia). Este encadenamiento significa que cada comparación se realiza en los dos argumentos que la rodean, con cada argumento interior participando en dos comparaciones, y los resultados de la comparación están implícitamente AND. Por lo tanto "$x < $y <= $z"
se comporta exactamente como "$x < $y && $y <= $z"
, asumiendo que "$y"
es un escalar tan simple como parece. El Ying cortocircuitos como "&&"
lo hace, deteniendo la secuencia de comparaciones tan pronto como se obtiene falso.
En una comparación encadenada, cada expresión de argumento se evalúa como máximo una vez, incluso si participa en dos comparaciones, pero el resultado de la evaluación se obtiene para cada comparación. (No se evalúa en absoluto si el cortocircuito significa que no es necesario para ninguna comparación). Esto es importante si el cálculo de un argumento interior es caro o no determinista. Por ejemplo,
if($x < expensive_sub() <= $z) { ...
no es del todo como
if($x < expensive_sub() && expensive_sub() <= $z) { ...
pero en cambio más cerca de
my $tmp = expensive_sub(); if($x < $tmp && $tmp <= $z) { ...
en que la subrutina solo se llama una vez. Sin embargo, tampoco es exactamente como este último código, porque la comparación encadenada en realidad no involucra ninguna variable temporal (nombrada o no): no hay asignación. Esto no hace mucha diferencia cuando la expresión es una llamada a una subrutina ordinaria, pero importa más con una subrutina lvalue, o si la expresión del argumento produce algún tipo de escalar inusual por otros medios. Por ejemplo, si la expresión del argumento produce un escalar vinculado, entonces la expresión se evalúa para producir ese escalar como máximo una vez, pero el valor de ese escalar puede obtenerse hasta dos veces, una vez para cada comparación en la que se utilice realmente.
En este ejemplo, la expresión se evalúa solo una vez y el escalar vinculado (el resultado de la expresión) se obtiene para cada comparación que lo usa.
if ($x < $tied_scalar < $z) { ...
En el siguiente ejemplo, la expresión se evalúa solo una vez y el escalar vinculado se recupera una vez como parte de la operación dentro de la expresión. El resultado de esa operación se obtiene para cada comparación, lo que normalmente no importa a menos que el resultado de la expresión también sea mágico debido a la sobrecarga del operador.
if ($x < $tied_scalar + 42 < $z) { ...
En cambio, algunos operadores son no asociativos, lo que significa que es un error de sintaxis usar una secuencia de esos operadores con la misma precedencia. Por ejemplo, "$x .. $y .. $z"
es un error.
Los operadores de Perl tienen la siguiente asociatividad y precedencia, enumeradas de mayor a menor precedencia. Los operadores tomados de C mantienen la misma relación de precedencia entre sí, incluso cuando la precedencia de C es un poco complicada. (Esto hace que el aprendizaje de Perl sea más fácil para la gente de C). Con muy pocas excepciones, todos estos operan solo con valores escalares, no con valores de matriz.
left terms and list operators (leftward) left -> nonassoc ++ -- right ** right ! ~ and unary + and - left =~ !~ left * / % x left + - . left << >> nonassoc named unary operators chained < > <= >= lt gt le ge chain/na == != eq ne <=> cmp ~~ nonassoc isa left & left | ^ left && left || // nonassoc .. ... right ?: right = += -= *= etc. goto last next redo dump left , => nonassoc list operators (rightward) right not left and left or xor
En las siguientes secciones, estos operadores se tratan en detalle, en el mismo orden en que aparecen en la tabla anterior.
Muchos operadores pueden estar sobrecargados de objetos. Ver sobrecarga.
Términos y operadores de lista (hacia la izquierda)
Un TERM tiene la mayor precedencia en Perl. Incluyen variables, operadores de comillas y similares, cualquier expresión entre paréntesis y cualquier función cuyos argumentos estén entre paréntesis. En realidad, no hay realmente funciones en este sentido, solo operadores de lista y operadores unarios que se comportan como funciones porque pones paréntesis alrededor de los argumentos. Todos estos están documentados en perlfunc.
Si algún operador de lista (print()
, etc.) o cualquier operador unario (chdir()
, etc.) va seguido de un paréntesis izquierdo como el siguiente token, el operador y los argumentos entre paréntesis se consideran de mayor precedencia, al igual que una llamada de función normal.
En ausencia de paréntesis, la precedencia de operadores de lista como print
, sort
, o chmod
es muy alto o muy bajo dependiendo de si está mirando al lado izquierdo o al lado derecho del operador. Por ejemplo, en
@ary = (1, 3, sort 4, 2); print @ary; # prints 1324
las comas a la derecha del sort
son evaluados antes del sort
, pero las comas de la izquierda se evalúan después. En otras palabras, los operadores de lista tienden a engullir todos los argumentos que siguen y luego actúan como un TÉRMINO simple con respecto a la expresión anterior. Tenga cuidado con los paréntesis:
# These evaluate exit before doing the print: print($foo, exit); # Obviously not what you want. print $foo, exit; # Nor is this. # These do the print before evaluating exit: (print $foo), exit; # This is what you want. print($foo), exit; # Or this. print ($foo), exit; # Or even this.
También tenga en cuenta que
print ($foo & 255) + 1, "n";
probablemente no haga lo que esperas a primera vista. Los paréntesis encierran la lista de argumentos para print
que se evalúa (imprimiendo el resultado de $foo & 255
). Luego se agrega uno al valor de retorno de print
(generalmente 1). El resultado es algo como esto:
1 + 1, "n"; # Obviously not what you meant.
Para hacer lo que quiso decir correctamente, debe escribir:
print(($foo & 255) + 1, "n");
Consulte “Operadores unarios nombrados” para obtener más información sobre esto.
También se analizan como términos los do {}
y eval {}
construcciones, así como llamadas a subrutinas y métodos, y los constructores anónimos []
y {}
.
Consulte también “Operadores de cotizaciones y similares a cotizaciones” al final de esta sección, así como “Operadores de E / S”.
El operador de flecha
“->
“es un operador de desreferencia infijo, tal como lo es en C y C ++. Si el lado derecho es un [...]
, {...}
o un (...)
subíndice, el lado izquierdo debe ser una referencia física o simbólica a una matriz, un hash o una subrutina, respectivamente. (O técnicamente hablando, una ubicación capaz de contener una referencia sólida, si es una referencia de matriz o hash que se utiliza para la asignación). Consulte perlreftut y perlref.
De lo contrario, el lado derecho es un nombre de método o una variable escalar simple que contiene el nombre del método o una referencia de subrutina, y el lado izquierdo debe ser un objeto (una referencia bendecida) o un nombre de clase (es decir, un nombre de paquete) . Ver perlobj.
Los casos de desreferenciación (a diferencia de los casos de llamadas a métodos) están algo extendidos por el postderef
característica. Para los detalles de esa característica, consulte “Sintaxis de desreferencia de postfijo” en perlref.
Auto-incremento y auto-decremento
"++"
y "--"
funcionan como en C. Es decir, si se colocan antes de una variable, aumentan o disminuyen la variable en uno antes de devolver el valor, y si se colocan después, aumentan o disminuyen después de devolver el valor.
$i = 0; $j = 0; print $i++; # prints 0 print ++$j; # prints 1
Tenga en cuenta que, al igual que en C, Perl no define cuando la variable se incrementa o decrementa. Solo sabe que se hará en algún momento antes o después de que se devuelva el valor. Esto también significa que modificar una variable dos veces en la misma declaración conducirá a un comportamiento indefinido. Evite declaraciones como:
$i = $i ++; print ++ $i + $i ++;
Perl no garantizará cuál es el resultado de las declaraciones anteriores.
El operador de incremento automático tiene un poco de magia adicional incorporada. Si incrementa una variable que es numérica, o que alguna vez se ha utilizado en un contexto numérico, obtiene un incremento normal. Sin embargo, si la variable se ha utilizado solo en contextos de cadena desde que se estableció, y tiene un valor que no es la cadena vacía y coincide con el patrón /^[a-zA-Z]*[0-9]*z/
, el incremento se realiza como una cadena, conservando cada carácter dentro de su rango, con acarreo:
print ++($foo = "99"); # prints "100" print ++($foo = "a0"); # prints "a1" print ++($foo = "Az"); # prints "Ba" print ++($foo = "zz"); # prints "aaa"
undef
siempre se trata como numérico y, en particular, se cambia a 0
antes de incrementar (para que un incremento posterior de un valor indefinido regrese 0
en vez de undef
).
El operador de auto-decremento no es mágico.
Exponenciación
Binario "**"
es el operador de exponenciación. Se une aún más fuerte que unario menos, por lo que -2**4
es -(2**4)
, no (-2)**4
. (Esto se implementa usando C’s pow(3)
función, que en realidad funciona en dobles internamente).
Tenga en cuenta que ciertas expresiones de exponenciación están mal definidas: estas incluyen 0**0
, 1**Inf
, y Inf**0
. No espere ningún resultado particular de estos casos especiales, los resultados dependen de la plataforma.
Operadores unarios simbólicos
Unario "!"
realiza una negación lógica, es decir, “no”. Ver también not
para una versión de menor precedencia de esto.
Unario "-"
realiza la negación aritmética si el operando es numérico, incluida cualquier cadena que parezca un número. Si el operando es un identificador, se devuelve una cadena que consta de un signo menos concatenado con el identificador. De lo contrario, si la cadena comienza con un signo más o menos, se devuelve una cadena que comienza con el signo opuesto. Un efecto de estas reglas es que -bareword
es equivalente a la cadena "-bareword"
. Sin embargo, si la cadena comienza con un carácter no alfabético (excluyendo "+"
o "-"
), Perl intentará convertir la cadena en numérica y se realizará la negación aritmética. Si la cadena no se puede convertir limpiamente a un número, Perl dará la advertencia El argumento “la cadena” no es numérico en la negación (-) en ….
Unario "~"
realiza la negación bit a bit, es decir, el complemento de 1. Por ejemplo, 0666 & ~027
es 0640. (Consulte también “Aritmética de enteros” y “Operadores de cadena de bits”.) Tenga en cuenta que el ancho del resultado depende de la plataforma: ~0
tiene 32 bits de ancho en una plataforma de 32 bits, pero 64 bits de ancho en una plataforma de 64 bits, por lo que si espera un cierto ancho de bits, recuerde usar el "&"
operador para enmascarar el exceso de bits.
A partir de Perl 5.28, es un error fatal intentar complementar una cadena que contiene un carácter con un valor ordinal superior a 255.
Si la función “bit a bit” está habilitada a través de use feature 'bitwise'
o use v5.28
, luego unario "~"
siempre trata su argumento como un número y una forma alternativa del operador, "~."
, siempre trata su argumento como una cadena. Entonces ~0
y ~"0"
ambos darán 2 ** 32-1 en plataformas de 32 bits, mientras que ~.0
y ~."0"
ambos cederán "xff"
. Hasta Perl 5.28, esta característica producía una advertencia en el "experimental::bitwise"
categoría.
Unario "+"
no tiene ningún efecto, incluso en las cuerdas. Es útil sintácticamente para separar el nombre de una función de una expresión entre paréntesis que de otro modo se interpretaría como la lista completa de argumentos de la función. (Consulte los ejemplos anteriores en “Términos y operadores de lista (hacia la izquierda)”).
Unario ""
crea referencias. Si su operando es una cosa con un solo signo, crea una referencia a ese objeto. Si su operando es una lista entre paréntesis, crea referencias a las cosas mencionadas en la lista. De lo contrario, coloca su operando en el contexto de lista y crea una lista de referencias a los escalares en la lista proporcionada por el operando. Consulte perlreftut y perlref. No confunda este comportamiento con el comportamiento de la barra invertida dentro de una cadena, aunque ambas formas transmiten la noción de proteger lo siguiente de la interpolación.
Operadores vinculantes
Binario "=~"
enlaza una expresión escalar a una coincidencia de patrón. Ciertas operaciones buscan o modifican la cadena $_
por defecto. Este operador hace que ese tipo de operación funcione en alguna otra cadena. El argumento correcto es un patrón de búsqueda, sustitución o transliteración. El argumento de la izquierda es lo que se supone que debe buscarse, sustituirse o transliterarse en lugar del predeterminado $_
. Cuando se usa en un contexto escalar, el valor de retorno generalmente indica el éxito de la operación. Las excepciones son la sustitución (s///
) y transliteración (y///
) con el /r
opción (no destructiva), que causa la rEl valor de retorno será el resultado de la sustitución. El comportamiento en el contexto de la lista depende del operador en particular. Consulte “Operadores Regexp Quote-Like” para más detalles y perlretut para ejemplos de uso de estos operadores.
Si el argumento correcto es una expresión en lugar de un patrón de búsqueda, sustitución o transliteración, se interpreta como un patrón de búsqueda en tiempo de ejecución. Tenga en cuenta que esto significa que su contenido se interpolará dos veces, por lo que
'\' =~ q'\';
no está bien, ya que el motor de expresiones regulares terminará intentando compilar el patrón , que considerará un error de sintaxis.
Binario "!~"
es como "=~"
excepto que el valor de retorno se niega en el sentido lógico.
Binario "!~"
con una sustitución no destructiva (s///r
) o transliteración (y///r
) es un error de sintaxis.
Operadores multiplicativos
Binario "*"
multiplica dos números.
Binario "https://foroayuda.es/"
divide dos números.
Binario "%"
es el operador de módulo, que calcula el resto de la división de su primer argumento con respecto a su segundo argumento. Operandos enteros dados $m
y $n
: Si $n
es positivo, entonces $m % $n
es $m
menos el mayor múltiplo de $n
Menos que o igual a $m
. Si $n
es negativo, entonces $m % $n
es $m
menos el múltiplo más pequeño de $n
eso no es menos que $m
(es decir, el resultado será menor o igual a cero). Si los operandos $m
y $n
son valores de coma flotante y el valor absoluto de $n
(es decir abs($n)
) es menos que (UV_MAX + 1)
, solo la parte entera de $m
y $n
se utilizará en la operación (Nota: aquí UV_MAX
significa el máximo del tipo entero sin signo). Si el valor absoluto del operando derecho (abs($n)
) es mayor o igual a (UV_MAX + 1)
, "%"
calcula el resto de punto flotante $r
en la ecuación ($r = $m - $i*$n)
dónde $i
es un número entero que hace $r
tienen el mismo signo que el operando derecho $n
(no como el operando izquierdo $m
como la función C fmod()
) y el valor absoluto menor que el de $n
. Tenga en cuenta que cuando use integer
está en el alcance, "%"
le da acceso directo al operador de módulo implementado por su compilador de C. Este operador no está tan bien definido para operandos negativos, pero se ejecutará más rápido.
Binario x
es el operador de repetición. En contexto escalar, o si el operando izquierdo no está entre paréntesis ni un qw//
lista, realiza una repetición de cadena. En ese caso, proporciona contexto escalar al operando izquierdo y devuelve una cadena que consta de la cadena del operando izquierdo repetida el número de veces especificado por el operando derecho. Si el x
está en contexto de lista, y el operando izquierdo está entre paréntesis o un qw//
lista, realiza una repetición de lista. En ese caso, proporciona contexto de lista al operando de la izquierda y devuelve una lista que consta de la lista de operandos de la izquierda repetida el número de veces especificado por el operando de la derecha. Si el operando derecho es cero o negativo (generando una advertencia en negativo), devuelve una cadena vacía o una lista vacía, según el contexto.
print '-' x 80; # print row of dashes print "t" x ($tab/8), ' ' x ($tab%8); # tab over @ones = (1) x 80; # a list of 80 1's @ones = (5) x @ones; # set all elements to 5
Operadores aditivos
Binario "+"
devuelve la suma de dos números.
Binario "-"
devuelve la diferencia de dos números.
Binario "."
concatena dos cadenas.
Operadores de turnos
Binario "<<"
devuelve el valor de su argumento de la izquierda desplazado a la izquierda por el número de bits especificado por el argumento de la derecha. Los argumentos deben ser números enteros. (Consulte también “Aritmética de enteros”).
Binario ">>"
devuelve el valor de su argumento de la izquierda desplazado a la derecha por el número de bits especificado por el argumento de la derecha. Los argumentos deben ser números enteros. (Consulte también “Aritmética de enteros”).
Si use integer
(ver “Aritmética de enteros”) está en vigor, entonces se utilizan enteros C con signo (cambio aritmético), de lo contrario se utilizan enteros C sin signo (cambio lógico), incluso para los cambiadores negativos. En el desplazamiento aritmético a la derecha, el bit de signo se replica a la izquierda, en el desplazamiento lógico, los bits cero entran desde la izquierda.
De cualquier manera, la implementación no generará resultados mayores que el tamaño del tipo entero con el que se construyó Perl (32 bits o 64 bits).
El desplazamiento por un número negativo de bits significa el desplazamiento inverso: el desplazamiento a la izquierda se convierte en desplazamiento a la derecha, el desplazamiento a la derecha se convierte en desplazamiento a la izquierda. Esto es diferente en C, donde el desplazamiento negativo no está definido.
Desplazarse en más bits que el tamaño de los enteros significa que la mayor parte del tiempo cero (todos los bits caen), excepto que bajo use integer
sobrepasar a la derecha un cambio negativo da como resultado -1. Esto es diferente en C, donde el desplazamiento de demasiados bits no está definido. Un comportamiento común de C es “desplazamiento por módulo de bits de palabra”, de modo que, por ejemplo,
1 >> 64 == 1 >> (64 % 64) == 1 >> 0 == 1 # Common C behavior.
pero eso es completamente accidental.
Si se cansa de estar sujeto a los enteros nativos de su plataforma, el use bigint
pragma elude perfectamente el problema por completo:
print 20 << 20; # 20971520 print 20 << 40; # 5120 on 32-bit machines, # 21990232555520 on 64-bit machines use bigint; print 20 << 100; # 25353012004564588029934064107520
Operadores unarios nombrados
Los diversos operadores unarios nombrados se tratan como funciones con un argumento, con paréntesis opcionales.
Si algún operador de lista (print()
, etc.) o cualquier operador unario (chdir()
, etc.) va seguido de un paréntesis izquierdo como el siguiente token, el operador y los argumentos entre paréntesis se consideran de mayor precedencia, al igual que una llamada de función normal. Por ejemplo, debido a que los operadores unarios con nombre tienen mayor precedencia que ||
:
chdir $foo || die; # (chdir $foo) || die chdir($foo) || die; # (chdir $foo) || die chdir ($foo) || die; # (chdir $foo) || die chdir +($foo) || die; # (chdir $foo) || die
pero porque "*"
tiene mayor precedencia que los operadores con nombre:
chdir $foo * 20; # chdir ($foo * 20) chdir($foo) * 20; # (chdir $foo) * 20 chdir ($foo) * 20; # (chdir $foo) * 20 chdir +($foo) * 20; # chdir ($foo * 20) rand 10 * 20; # rand (10 * 20) rand(10) * 20; # (rand 10) * 20 rand (10) * 20; # (rand 10) * 20 rand +(10) * 20; # rand (10 * 20)
Con respecto a la precedencia, los operadores de prueba de archivos, como -f
, -M
, etc. se tratan como operadores unarios con nombre, pero no siguen esta regla funcional de paréntesis. Eso significa, por ejemplo, que -f($file).".bak"
es equivalente a -f "$file.bak"
.
Consulte también “Términos y operadores de lista (hacia la izquierda)”.
Operadores relacionales
Los operadores de Perl que devuelven verdadero o falso generalmente devuelven valores que se pueden usar con seguridad como números. Por ejemplo, los operadores relacionales en esta sección y los operadores de igualdad en la siguiente devuelven 1
para verdadero y una versión especial de la cadena vacía definida, ""
, que cuenta como cero pero está exento de advertencias sobre conversiones numéricas incorrectas, al igual que "0 but true"
es.
Binario "<"
devuelve verdadero si el argumento de la izquierda es numéricamente menor que el de la derecha.
Binario ">"
devuelve verdadero si el argumento de la izquierda es numéricamente mayor que el de la derecha.
Binario "<="
devuelve verdadero si el argumento de la izquierda es numéricamente menor o igual que el argumento de la derecha.
Binario ">="
devuelve verdadero si el argumento de la izquierda es numéricamente mayor o igual que el argumento de la derecha.
Binario "lt"
devuelve verdadero si el argumento de la izquierda es una cadena menor que el argumento de la derecha.
Binario "gt"
devuelve verdadero si el argumento de la izquierda es una cadena mayor que el argumento de la derecha.
Binario "le"
devuelve verdadero si el argumento de la izquierda es en sentido de cadena menor o igual que el argumento de la derecha.
Binario "ge"
devuelve verdadero si el argumento de la izquierda es una cadena mayor o igual que el argumento de la derecha.
Una secuencia de operadores relacionales, como "$x < $y <= $z"
, realiza comparaciones encadenadas, de la manera descrita anteriormente en la sección “Precedencia y asociatividad del operador”. Tenga en cuenta que no se encadenan con operadores de igualdad, que tienen menor precedencia.
Operadores de igualdad
Binario "=="
devuelve verdadero si el argumento de la izquierda es numéricamente igual al argumento de la derecha.
Binario "!="
devuelve verdadero si el argumento de la izquierda no es numéricamente igual al argumento de la derecha.
Binario "eq"
devuelve verdadero si el argumento de la izquierda es igual en cadena al argumento de la derecha.
Binario "ne"
devuelve verdadero si el argumento de la izquierda no es igual al argumento de la derecha.
Una secuencia de los operadores de igualdad anteriores, como "$x == $y == $z"
, realiza comparaciones encadenadas, de la manera descrita anteriormente en la sección “Precedencia y asociatividad del operador”. Tenga en cuenta que no se encadenan con operadores relacionales, que tienen mayor precedencia.
Binario "<=>"
devuelve -1, 0 o 1 dependiendo de si el argumento de la izquierda es numéricamente menor, igual o mayor que el argumento de la derecha. Si su plataforma es compatible NaN
‘s (no-a-números) como valores numéricos, usándolos con "<=>"
devuelve undef. NaN
no es "<"
, "=="
, ">"
, "<="
o ">="
cualquier cosa (incluso NaN
), por lo que esos 5 devuelven falso. NaN != NaN
devuelve verdadero, al igual que NaN !=
Algo más. Si su plataforma no es compatible NaN
es entonces NaN
es solo una cadena con valor numérico 0.
$ perl -le '$x = "NaN"; print "No NaN support here" if $x == $x' $ perl -le '$x = "NaN"; print "NaN support here" if $x != $x'
(Tenga en cuenta que los pragmas bigint, bigrat y bignum son compatibles "NaN"
.)
Binario "cmp"
devuelve -1, 0 o 1 dependiendo de si el argumento de la izquierda es menor, igual o mayor que el argumento de la derecha.
Binario "~~"
hace una coincidencia inteligente entre sus argumentos. La coincidencia inteligente se describe en la siguiente sección.
Los operadores de pedidos de dos caras "<=>"
y "cmp"
y el operador smartmatch "~~"
, son no asociativos entre sí y con respecto a los operadores de igualdad de la misma precedencia.
"lt"
, "le"
, "ge"
, "gt"
y "cmp"
utilizar el orden de clasificación (clasificación) especificado por el actual LC_COLLATE
local si un use locale
el formulario que incluye la colación está en vigor. Ver perllocale. No los mezcle con Unicode, solo utilícelos con codificaciones de configuración regional de 8 bits heredadas. El estandar Unicode::Collate
y Unicode::Collate::Locale
Los módulos ofrecen soluciones mucho más potentes a los problemas de intercalación.
Para realizar comparaciones que no distinguen entre mayúsculas y minúsculas, observe el “fc” en la función de plegado de mayúsculas y minúsculas perlfunc, disponible en Perl v5.16 o posterior:
if ( fc($x) eq fc($y) ) { ... }
Operador de instancia de clase
Binario isa
se evalúa como verdadero cuando el argumento de la izquierda es una instancia de objeto de la clase (o una subclase derivada de esa clase) dada por el argumento de la derecha. Si el argumento de la izquierda no está definido, no es una instancia de objeto bendecido, ni se deriva de la clase dada por el argumento de la derecha, el operador se evalúa como falso. El argumento correcto puede dar la clase como una palabra simple o una expresión escalar que produce un nombre de clase de cadena:
if( $obj isa Some::Class ) { ... } if( $obj isa "Different::Class" ) { ... } if( $obj isa $name_of_class ) { ... }
Esta es una función experimental y está disponible en Perl 5.31.6 cuando está habilitada por use feature 'isa'
. Emite una advertencia en el experimental::isa
categoría.
Operador de Smartmatch
Primero disponible en Perl 5.10.1 (la versión 5.10.0 se comportó de manera diferente), binario ~~
hace un “smartmatch” entre sus argumentos. Esto se usa principalmente implícitamente en el when
constructo descrito en Perlsyn, aunque no todos when
las cláusulas llaman al operador smartmatch. Único entre todos los operadores de Perl, el operador de smartmatch puede recurrir. El operador de smartmatch es experimental y su comportamiento está sujeto a cambios.
También es único en el sentido de que todos los demás operadores de Perl imponen un contexto (generalmente un contexto de cadena o numérico) en sus operandos, convirtiendo automáticamente esos operandos a esos contextos impuestos. Por el contrario, smartmatch infiere contextos de los tipos reales de sus operandos y utiliza ese tipo de información para seleccionar un mecanismo de comparación adecuado.
los ~~
El operador compara sus operandos “polimórficamente”, determinando cómo compararlos de acuerdo con sus tipos reales (numérico, cadena, matriz, hash, etc.). Como los operadores de igualdad con los que comparte la misma precedencia, ~~
devuelve 1 para verdadero y ""
por falso. A menudo, es mejor leerlo en voz alta como “en”, “dentro de” o “está contenido en”, porque el operando izquierdo a menudo se busca dentro el operando correcto. Eso hace que el orden de los operandos al operando de coincidencia inteligente a menudo sea opuesto al del operador de coincidencia normal. En otras palabras, lo “más pequeño” generalmente se coloca en el operando izquierdo y el más grande en el derecho.
El comportamiento de un smartmatch depende del tipo de cosas que sean sus argumentos, según lo determinado por la siguiente tabla. La primera fila de la tabla cuyos tipos se aplican determina el comportamiento de Smartmatch. Debido a que lo que realmente sucede está determinado principalmente por el tipo del segundo operando, la tabla se ordena por el operando derecho en lugar de por el izquierdo.
Left Right Description and pseudocode =============================================================== Any undef check whether Any is undefined like: !defined Any Any Object invoke ~~ overloading on Object, or die Right operand is an ARRAY: Left Right Description and pseudocode =============================================================== ARRAY1 ARRAY2 recurse on paired elements of ARRAY1 and ARRAY2[2] like: (ARRAY1[0] ~~ ARRAY2[0]) && (ARRAY1[1] ~~ ARRAY2[1]) && ... HASH ARRAY any ARRAY elements exist as HASH keys like: grep { exists HASH->{$_} } ARRAY Regexp ARRAY any ARRAY elements pattern match Regexp like: grep { /Regexp/ } ARRAY undef ARRAY undef in ARRAY like: grep { !defined } ARRAY Any ARRAY smartmatch each ARRAY element[3] like: grep { Any ~~ $_ } ARRAY Right operand is a HASH: Left Right Description and pseudocode =============================================================== HASH1 HASH2 all same keys in both HASHes like: keys HASH1 == grep { exists HASH2->{$_} } keys HASH1 ARRAY HASH any ARRAY elements exist as HASH keys like: grep { exists HASH->{$_} } ARRAY Regexp HASH any HASH keys pattern match Regexp like: grep { /Regexp/ } keys HASH undef HASH always false (undef can't be a key) like: 0 == 1 Any HASH HASH key existence like: exists HASH->{Any} Right operand is CODE: Left Right Description and pseudocode =============================================================== ARRAY CODE sub returns true on all ARRAY elements[1] like: !grep { !CODE->($_) } ARRAY HASH CODE sub returns true on all HASH keys[1] like: !grep { !CODE->($_) } keys HASH Any CODE sub passed Any returns true like: CODE->(Any)
El operando derecho es una expresión regular:
Left Right Description and pseudocode =============================================================== ARRAY Regexp any ARRAY elements match Regexp like: grep { /Regexp/ } ARRAY HASH Regexp any HASH keys match Regexp like: grep { /Regexp/ } keys HASH Any Regexp pattern match like: Any =~ /Regexp/ Other: Left Right Description and pseudocode =============================================================== Object Any invoke ~~ overloading on Object, or fall back to... Any Num numeric equality like: Any == Num Num nummy[4] numeric equality like: Num == nummy undef Any check whether undefined like: !defined(Any) Any Any string equality like: Any eq Any
Notas:
- 1. Coincidencia de hashes o matrices vacías.
- 2. Es decir, cada elemento coincide inteligentemente con el elemento del mismo índice en la otra matriz.[3]
- 3. Si se encuentra una referencia circular, recurra a la igualdad referencial.
- 4. O un número real o una cadena que parece uno.
Smartmatch elimina implícitamente cualquier referencia de matriz o hash no bendecida, por lo que HASH
y ARRAY
las entradas se aplican en esos casos. Para benditas referencias, el Object
se aplican entradas. Las coincidencias inteligentes que involucran hashes solo consideran claves hash, nunca valores hash.
La entrada del código “me gusta” no siempre es una interpretación exacta. Por ejemplo, el operador de smartmatch cortocircuita siempre que sea posible, pero grep
no. También, grep
en contexto escalar devuelve el número de coincidencias, pero ~~
devuelve solo verdadero o falso.
A diferencia de la mayoría de los operadores, el operador de smartmatch sabe tratar undef
especialmente:
use v5.10.1; @array = (1, 2, 3, undef, 4, 5); say "some elements undefined" if undef ~~ @array;
Cada operando se considera en un contexto escalar modificado, la modificación es que las variables de matriz y hash se pasan por referencia al operador, que implícitamente las desreferencia. Ambos elementos de cada par son iguales:
use v5.10.1; my %hash = (red => 1, blue => 2, green => 3, orange => 4, yellow => 5, purple => 6, black => 7, grey => 8, white => 9); my @array = qw(red blue green); say "some array elements in hash keys" if @array ~~ %hash; say "some array elements in hash keys" if @array ~~ %hash; say "red in array" if "red" ~~ @array; say "red in array" if "red" ~~ @array; say "some keys end in e" if /e$/ ~~ %hash; say "some keys end in e" if /e$/ ~~ %hash;
Dos matrices se emparejan inteligentemente si cada elemento de la primera matriz empareja inteligentemente (es decir, está “en”) el elemento correspondiente en la segunda matriz, de forma recursiva.
use v5.10.1; my @little = qw(red blue green); my @bigger = ("red", "blue", [ "orange", "green" ] ); if (@little ~~ @bigger) { # true! say "little is contained in bigger"; }
Debido a que el operador smartmatch recurre en matrices anidadas, esto aún informará que “rojo” está en la matriz.
use v5.10.1; my @array = qw(red blue green); my $nested_array = [[[[[[[ @array ]]]]]]]; say "red in array" if "red" ~~ $nested_array;
Si dos matrices se emparejan de forma inteligente entre sí, entonces son copias profundas de los valores de cada uno, como informa este ejemplo:
use v5.12.0; my @a = (0, 1, 2, [3, [4, 5], 6], 7); my @b = (0, 1, 2, [3, [4, 5], 6], 7); if (@a ~~ @b && @b ~~ @a) { say "a and b are deep copies of each other"; } elsif (@a ~~ @b) { say "a smartmatches in b"; } elsif (@b ~~ @a) { say "b smartmatches in a"; } else { say "a and b don't smartmatch each other at all"; }
Si tuvieras que establecer $b[3] = 4
, luego, en lugar de informar que “ayb son copias profundas el uno del otro”, ahora Informes que "b smartmatches in a"
. Eso es porque la posición correspondiente en @a
contiene una matriz que (eventualmente) tiene un 4.
La comparación inteligente de un hash con otro informa si ambos contienen las mismas claves, ni más ni menos. Esto podría usarse para ver si dos registros tienen los mismos nombres de campo, sin importar los valores que puedan tener esos campos. Por ejemplo:
use v5.10.1; sub make_dogtag { state $REQUIRED_FIELDS = { name=>1, rank=>1, serial_num=>1 }; my ($class, $init_fields) = @_; die "Must supply (only) name, rank, and serial number" unless $init_fields ~~ $REQUIRED_FIELDS; ... }
Sin embargo, esto solo hace lo que quieres decir si $init_fields
es de hecho una referencia hash. La condición $init_fields ~~ $REQUIRED_FIELDS
también permite las cuerdas "name"
, "rank"
, "serial_num"
así como cualquier referencia de matriz que contenga "name"
o "rank"
o "serial_num"
en cualquier lugar para pasar.
El operador smartmatch se utiliza con mayor frecuencia como operador implícito de un when
cláusula. Consulte la sección sobre “Declaraciones de cambio” en perlsyn.
Coincidencia inteligente de objetos
Para evitar depender de la representación subyacente de un objeto, si el operando derecho de smartmatch es un objeto que no se sobrecarga ~~
, genera la excepción “Smartmatching a non-overloaded object breaks encapsulation
“. Eso es porque uno no tiene por qué investigar para ver si algo está” en “un objeto. Todo esto es ilegal en objetos sin un ~~
sobrecarga:
%hash ~~ $object 42 ~~ $object "fred" ~~ $object
Sin embargo, puede cambiar la forma en que un objeto se empareja de forma inteligente sobrecargando el ~~
operador. Esto permite extender la semántica habitual de smartmatch. Para los objetos que tienen un ~~
sobrecarga, ver sobrecarga.
Se permite usar un objeto como operando izquierdo, aunque no es muy útil. Las reglas de Smartmatching tienen prioridad sobre la sobrecarga, por lo que incluso si el objeto del operando izquierdo tiene una sobrecarga de Smartmatch, esto se ignorará. Un operando izquierdo que es un objeto no sobrecargado recurre a una cadena o comparación numérica de lo que sea ref
regresa el operador. Eso significa que
$object ~~ X
lo hace no invocar el método de sobrecarga con X
como argumento. En cambio, la tabla anterior se consulta con normalidad y se basa en el tipo de X
, la sobrecarga puede invocarse o no. Para cadenas o números simples, “in” se convierte en equivalente a esto:
$object ~~ $number ref($object) == $number $object ~~ $string ref($object) eq $string
Por ejemplo, esto informa que el mango huele a IOish (¡pero por favor, no hagas esto!):
use IO::Handle; my $fh = IO::Handle->new(); if ($fh ~~ /bIOb/) { say "handle smells IOish"; }
Eso es porque trata $fh
como una cuerda como "IO::Handle=GLOB(0x8039e0)"
, luego el patrón coincide con eso.
Bit a bit y
Binario "&"
devuelve sus operandos AND juntos bit a bit. Aunque actualmente no se emite ninguna advertencia, el resultado no está bien definido cuando esta operación se realiza en operandos que no son números (consulte “Aritmética de enteros”) ni cadenas de bits (consulte “Operadores de cadenas de bits”).
Tenga en cuenta que "&"
tiene menor prioridad que los operadores relacionales, por lo que, por ejemplo, los paréntesis son esenciales en una prueba como
print "Evenn" if ($x & 1) == 0;
Si la función “bit a bit” está habilitada a través de use feature 'bitwise'
o use v5.28
, entonces este operador siempre trata sus operandos como números. Antes de Perl 5.28, esta característica producía una advertencia en el "experimental::bitwise"
categoría.
O bit a bit y O exclusivo
Binario "|"
devuelve sus operandos OR juntos bit a bit.
Binario "^"
devuelve sus operandos XOR juntos bit a bit.
Aunque actualmente no se genera ninguna advertencia, los resultados no están bien definidos cuando estas operaciones se realizan en operandos que no son números (consulte “Aritmética de enteros”) ni cadenas de bits (consulte “Operadores de cadenas de bits”).
Tenga en cuenta que "|"
y "^"
tienen menor prioridad que los operadores relacionales, por lo que, por ejemplo, los paréntesis son esenciales en una prueba como
print "falsen" if (8 | 2) != 10;
Si la función “bit a bit” está habilitada a través de use feature 'bitwise'
o use v5.28
, entonces este operador siempre trata sus operandos como números. Antes de Perl 5.28. esta característica produjo una advertencia en el "experimental::bitwise"
categoría.
Lógico estilo C y
Binario "&&"
realiza una operación Y lógica de cortocircuito. Es decir, si el operando izquierdo es falso, el operando derecho ni siquiera se evalúa. El contexto escalar o de lista se propaga hacia el operando derecho si se evalúa.
O lógico de estilo C
Binario "||"
realiza una operación OR lógica de cortocircuito. Es decir, si el operando izquierdo es verdadero, el operando derecho ni siquiera se evalúa. El contexto escalar o de lista se propaga hacia el operando derecho si se evalúa.
Definido lógico-Or
Aunque no tiene equivalente directo en C, Perl //
El operador está relacionado con su estilo C “o”. De hecho, es exactamente lo mismo que ||
, excepto que prueba la definición del lado izquierdo en lugar de su verdad. Por lo tanto, EXPR1 // EXPR2
devuelve el valor de EXPR1
si está definido, de lo contrario, el valor de EXPR2
es regresado. (EXPR1
se evalúa en contexto escalar, EXPR2
en el contexto de //
sí mismo). Por lo general, este es el mismo resultado que defined(EXPR1) ? EXPR1 : EXPR2
(excepto que la forma del operador ternario se puede usar como un valor l, mientras que EXPR1 // EXPR2
no poder). Esto es muy útil para proporcionar valores predeterminados para variables. Si realmente desea probar si al menos uno de $x
y $y
está definido, usar defined($x // $y)
.
los ||
, //
y &&
Los operadores devuelven el último valor evaluado (a diferencia de C ||
y &&
, que devuelven 0 o 1). Por lo tanto, una forma razonablemente portátil de encontrar el directorio de inicio podría ser:
$home = $ENV{HOME} // $ENV{LOGDIR} // (getpwuid($<))[7] // die "You're homeless!n";
En particular, esto significa que no debe usar esto para seleccionar entre dos agregados para la asignación:
@a = @b || @c; # This doesn't do the right thing @a = scalar(@b) || @c; # because it really means this. @a = @b ? @b : @c; # This works fine, though.
Como alternativas a &&
y ||
cuando se utiliza para controlar el flujo, Perl proporciona la and
y or
operadores (ver más abajo). El comportamiento de cortocircuito es idéntico. La precedencia de "and"
y "or"
es mucho más bajo, sin embargo, para que pueda usarlos de manera segura después de un operador de lista sin la necesidad de paréntesis:
unlink "alpha", "beta", "gamma" or gripe(), next LINE;
Con los operadores de estilo C que se habrían escrito así:
unlink("alpha", "beta", "gamma") || (gripe(), next LINE);
Sería aún más legible escribir eso de esta manera:
unless(unlink("alpha", "beta", "gamma")) { gripe(); next LINE; }
Utilizando "or"
para la asignación es poco probable que haga lo que quiere; vea abajo.
Operadores de rango
Binario ".."
es el operador de rango, que en realidad son dos operadores diferentes según el contexto. En el contexto de la lista, devuelve una lista de valores contando (de a uno) desde el valor de la izquierda al valor de la derecha. Si el valor de la izquierda es mayor que el valor de la derecha, devuelve la lista vacía. El operador de rango es útil para escribir foreach (1..10)
bucles y para realizar operaciones de corte en matrices. En la implementación actual, no se crea una matriz temporal cuando el operador de rango se usa como expresión en foreach
bucles, pero las versiones anteriores de Perl pueden quemar mucha memoria cuando escribe algo como esto:
for (1 .. 1_000_000) { # code }
El operador de rango también trabaja en cadenas, usando el mágico incremento automático, ver más abajo.
En contexto escalar, ".."
devuelve un valor booleano. El operador es biestable, como un flip-flop, y emula el operador de rango de línea (coma) de sed, awky varios editores. Cada ".."
El operador mantiene su propio estado booleano, incluso a través de llamadas a una subrutina que lo contiene. Es falso siempre que su operando izquierdo sea falso. Una vez que el operando izquierdo es verdadero, el operador de rango permanece verdadero hasta que el operando derecho es verdadero, DESPUÉS que el operador de rango se vuelve falso nuevamente. No se vuelve falso hasta la próxima vez que se evalúa el operador de rango. Puede probar el operando correcto y volverse falso en la misma evaluación en la que se convirtió en verdadero (como en awk), pero aún devuelve verdadero una vez. Si no quiere que pruebe el operando correcto hasta la próxima evaluación, como en sed, solo usa tres puntos ("..."
) en lugar de dos. En todos los demás aspectos, "..."
se comporta como ".."
lo hace.
El operando derecho no se evalúa mientras el operador está en el estado “falso”, y el operando izquierdo no se evalúa mientras el operador está en el estado “verdadero”. La precedencia es un poco menor que || y &&. El valor devuelto es la cadena vacía para falso o un número de secuencia (que comienza con 1) para verdadero. El número de secuencia se restablece para cada rango encontrado. El número de secuencia final en un rango tiene la cadena "E0"
agregado a él, lo que no afecta su valor numérico, pero le da algo para buscar si desea excluir el punto final. Puede excluir el punto de inicio esperando que el número de secuencia sea mayor que 1.
Si cualquiera de los operandos de escalar ".."
es una expresión constante, ese operando se considera verdadero si es igual (==
) al número de línea de entrada actual (el $.
variable).
Para ser pedante, la comparación es en realidad int(EXPR) == int(EXPR)
, pero eso solo es un problema si usa una expresión de punto flotante; cuando se usa implícitamente $.
como se describe en el párrafo anterior, la comparación es int(EXPR) == int($.)
que es solo un problema cuando $.
está establecido en un valor de punto flotante y no está leyendo de un archivo. Es más, "span" .. "spat"
o 2.18 .. 3.14
no hará lo que desea en el contexto escalar porque cada uno de los operandos se evalúa utilizando su representación entera.
Ejemplos:
Como operador escalar:
if (101 .. 200) { print; } # print 2nd hundred lines, short for # if ($. == 101 .. $. == 200) { print; } next LINE if (1 .. /^$/); # skip header lines, short for # next LINE if ($. == 1 .. /^$/); # (typically in a loop labeled LINE) s/^/> / if (/^$/ .. eof()); # quote body # parse mail messages while (<>) { $in_header = 1 .. /^$/; $in_body = /^$/ .. eof; if ($in_header) { # do something } else { # in body # do something else } } continue { close ARGV if eof; # reset $. each file }
Aquí hay un ejemplo simple para ilustrar la diferencia entre los dos operadores de rango:
@lines = (" - Foo", "01 - Bar", "1 - Baz", " - Quux"); foreach (@lines) { if (/0/ .. /1/) { print "$_n"; } }
Este programa imprimirá solo la línea que contiene “Bar”. Si el operador de rango se cambia a ...
, también imprimirá la línea “Baz”.
Y ahora algunos ejemplos como operador de lista:
for (101 .. 200) { print } # print $_ 100 times @foo = @foo[0 .. $#foo]; # an expensive no-op @foo = @foo[$#foo-4 .. $#foo]; # slice last 5 items
Dado que cada operando se evalúa en forma de entero, 2.18 .. 3.14
devolverá dos elementos en el contexto de la lista.
@list = (2.18 .. 3.14); # same as @list = (2 .. 3);
El operador de rango en el contexto de lista puede hacer uso del algoritmo mágico de incremento automático si ambos operandos son cadenas, sujeto a las siguientes reglas:
-
Con una excepción (a continuación), si ambas cadenas parecen números para Perl, el incremento mágico no se aplicará y las cadenas se tratarán como números (más específicamente, enteros) en su lugar.
Por ejemplo,
"-2".."2"
es lo mismo que-2..2
, y"2.18".."3.14"
produce2, 3
. -
La excepción a lo anterior La regla es cuando la cuerda de la izquierda comienza con
0
y tiene más de un carácter, en este caso el incremento mágico voluntad ser aplicado, aunque cadenas como"01"
normalmente se vería como un número para Perl.Por ejemplo,
"01".."04"
produce"01", "02", "03", "04"
, y"00".."-1"
produce"00"
mediante"99"
– esto puede parecer sorprendente, pero consulte las siguientes reglas sobre por qué funciona de esta manera. Para obtener fechas con ceros a la izquierda, puede decir:@z2 = ("01" .. "31"); print $z2[$mday];
Si desea forzar que las cadenas se interpreten como números, podría decir
@numbers = ( 0+$first .. 0+$last );
-
Si el valor inicial especificado no forma parte de una secuencia de incremento mágico (es decir, una cadena no vacía que coincide
/^[a-zA-Z]*[0-9]*z/
), solo se devolverá el valor inicial.Por ejemplo,
"ax".."az"
produce"ax", "ay", "az"
, pero"*x".."az"
produce solo"*x"
. -
Para otros valores iniciales que son cadenas que siguen las reglas del incremento mágico, se devolverá la secuencia correspondiente.
Por ejemplo, puedes decir
@alphabet = ("A" .. "Z");
para obtener todas las letras normales del alfabeto inglés, o
$hexdigit = (0 .. 9, "a" .. "f")[$num & 15];
para obtener un dígito hexadecimal.
-
Si el valor final especificado no está en la secuencia que produciría el incremento mágico, la secuencia continúa hasta que el siguiente valor sea más largo que el valor final especificado. Si la longitud de la cadena final es más corta que la primera, se devuelve la lista vacía.
Por ejemplo,
"a".."--"
es lo mismo que"a".."zz"
,"0".."xx"
produce"0"
mediante"99"
, y"aaa".."--"
devuelve la lista vacía.
A partir de Perl 5.26, el operador de rango de contexto de lista en cadenas funciona como se esperaba en el alcance de "use feature 'unicode_strings"
. En versiones anteriores, y fuera del alcance de esa característica, exhibe “El” Error Unicode “” en perlunicode: su comportamiento depende de la codificación interna del punto final del rango.
Porque el incremento mágico solo funciona en cadenas no vacías que coinciden /^[a-zA-Z]*[0-9]*z/
, lo siguiente solo devolverá un alfa:
use charnames "greek"; my @greek_small = ("N{alpha}" .. "N{omega}");
Para obtener las 25 letras griegas minúsculas tradicionales, incluidos ambos sigmas, puede usar esto en su lugar:
use charnames "greek"; my @greek_small = map { chr } ( ord("N{alpha}") .. ord("N{omega}") );
Sin embargo, debido a que hay muchos otros caracteres griegos en minúscula además de esos, para hacer coincidir los caracteres griegos en minúscula en una expresión regular, puede utilizar el patrón /(?:(?=p{Greek})p{Lower})+/
(o la función experimental /(?[ p{Greek} & p{Lower} ])+/
).
Operador condicional
Ternario "?:"
es el operador condicional, al igual que en C. Funciona de forma muy similar a un if-then-else. Si el argumento antes del ?
es cierto, el argumento antes de la :
se devuelve, de lo contrario, el argumento después de la :
es regresado. Por ejemplo:
printf "I have %d dog%s.n", $n, ($n == 1) ? "" : "s";
El contexto escalar o de lista se propaga hacia abajo en el segundo o tercer argumento, el que se seleccione.
$x = $ok ? $y : $z; # get a scalar @x = $ok ? @y : @z; # get an array $x = $ok ? @y : @z; # oops, that's just a count!
El operador puede asignarse a si tanto el segundo como el tercer argumento son valores legales (lo que significa que puede asignarles):
($x_or_y ? $x : $y) = $z;
Debido a que este operador produce un resultado asignable, el uso de asignaciones sin paréntesis lo meterá en problemas. Por ejemplo, esto:
$x % 2 ? $x += 10 : $x += 2
Realmente significa esto:
(($x % 2) ? ($x += 10) : $x) += 2
En vez de esto:
($x % 2) ? ($x += 10) : ($x += 2)
Eso probablemente debería escribirse de manera más simple como:
$x += ($x % 2) ? 10 : 2;
Operadores de Asignación
"="
es el operador de asignación ordinario.
Los operadores de asignación funcionan como en C. Es decir,
$x += 2;
es equivalente a
$x = $x + 2;
aunque sin duplicar los efectos secundarios que podría desencadenar la desreferenciación del valor l, como tie()
. Otros operadores de asignación funcionan de manera similar. Se reconocen los siguientes:
**= += *= &= &.= <<= &&= -= /= |= |.= >>= ||= .= %= ^= ^.= //= x=
Aunque están agrupados por familia, todos tienen prioridad de asignación. Estos operadores de asignación combinados solo pueden operar en escalares, mientras que el operador de asignación ordinario puede asignar a matrices, hashes, listas e incluso referencias. (Consulte “Contexto” y “Constructores de valor de lista” en perldata y “Asignación a referencias” en perlref).
A diferencia de C, el operador de asignación escalar produce un valor l válido. Modificar una asignación equivale a realizar la asignación y luego modificar la variable a la que se asignó. Esto es útil para modificar una copia de algo, como esto:
($tmp = $global) =~ tr/13579/24680/;
Aunque a partir de 5.14, eso también se puede lograr de esta manera:
use v5.14; $tmp = ($global =~ tr/13579/24680/r);
Igualmente,
($x += 2) *= 3;
es equivalente a
$x += 2; $x *= 3;
De manera similar, una asignación de lista en contexto de lista produce la lista de valores l asignados a, y una asignación de lista en contexto escalar devuelve el número de elementos producidos por la expresión en el lado derecho de la asignación.
Los tres operadores de asignación bit a bit con puntos (&.=
|.=
^.=
) son nuevas en Perl 5.22. Consulte “Operadores de cadenas de bits”.
Operador de coma
Binario ","
es el operador de coma. En contexto escalar, evalúa su argumento izquierdo, descarta ese valor, luego evalúa su argumento derecho y devuelve ese valor. Esto es como el operador de coma de C.
En el contexto de la lista, es solo el separador de argumentos de la lista e inserta ambos argumentos en la lista. Estos argumentos también se evalúan de izquierda a derecha.
los =>
operador (a veces pronunciado “coma gruesa”) es un sinónimo de la coma, excepto que hace que una palabra a su izquierda se interprete como una cadena si comienza con una letra o un guión bajo y está compuesta solo de letras, dígitos y guiones bajos. Esto incluye operandos que de otro modo podrían interpretarse como operadores, constantes, cadenas v de un solo número o llamadas a funciones. Si tiene dudas sobre este comportamiento, el operando izquierdo se puede citar explícitamente.
De lo contrario, el =>
El operador se comporta exactamente como el operador de coma o el separador de argumentos de lista, según el contexto.
Por ejemplo:
use constant FOO => "something"; my %h = ( FOO => 23 );
es equivalente a:
my %h = ("FOO", 23);
Está NO:
my %h = ("something", 23);
los =>
El operador es útil para documentar la correspondencia entre claves y valores en hashes y otros elementos emparejados en listas.
%hash = ( $key => $value ); login( $username => $password );
El comportamiento de cotización especial ignora la precedencia y, por lo tanto, puede aplicarse a parte del operando izquierdo:
print time.shift => "bbb";
Ese ejemplo imprime algo como "1314363215shiftbbb"
, porque el =>
cita implícitamente el shift
inmediatamente a su izquierda, ignorando el hecho de que time.shift
es el operando izquierdo completo.
Operadores de lista (hacia la derecha)
En el lado derecho de un operador de lista, la coma tiene una precedencia muy baja, de modo que controla todas las expresiones separadas por comas que se encuentran allí. Los únicos operadores con menor precedencia son los operadores lógicos "and"
, "or"
, y "not"
, que puede usarse para evaluar llamadas a operadores de lista sin la necesidad de paréntesis:
open HANDLE, "< :encoding(UTF-8)", "filename" or die "Can't open: $!n";
Sin embargo, algunas personas encuentran ese código más difícil de leer que escribirlo entre paréntesis:
open(HANDLE, "< :encoding(UTF-8)", "filename") or die "Can't open: $!n";
en cuyo caso también podría utilizar el más habitual "||"
operador:
open(HANDLE, "< :encoding(UTF-8)", "filename") || die "Can't open: $!n";
Consulte también la discusión sobre los operadores de lista en “Términos y operadores de lista (hacia la izquierda)”.
Lógico no
Unario "not"
devuelve la negación lógica de la expresión a su derecha. Es el equivalente de "!"
excepto por la muy baja precedencia.
Lógico y
Binario "and"
devuelve la conjunción lógica de las dos expresiones circundantes. Es equivalente a &&
excepto por la muy baja precedencia. Esto significa que se produce un cortocircuito: la expresión de la derecha se evalúa solo si la expresión de la izquierda es verdadera.
O lógico y exclusivo O
Binario "or"
devuelve la disyunción lógica de las dos expresiones circundantes. Es equivalente a ||
excepto por la muy baja precedencia. Esto lo hace útil para controlar el flujo:
print FH $data or die "Can't write to FH: $!";
Esto significa que se produce un cortocircuito: la expresión de la derecha se evalúa solo si la expresión de la izquierda es falsa. Debido a su precedencia, debe tener cuidado de no usarlo como reemplazo del ||
operador. Por lo general, funciona mejor para el control de flujo que en las asignaciones:
$x = $y or $z; # bug: this is wrong ($x = $y) or $z; # really means this $x = $y || $z; # better written this way
Sin embargo, cuando se trata de una asignación de contexto de lista y está intentando usar ||
para controlar el flujo, probablemente necesite "or"
para que la asignación tenga mayor prioridad.
@info = stat($file) || die; # oops, scalar sense of stat! @info = stat($file) or die; # better, now @info gets its due
Por otra parte, siempre puedes usar paréntesis.
Binario "xor"
devuelve el OR exclusivo de las dos expresiones circundantes. No puede cortocircuitar (por supuesto).
No hay un operador de baja precedencia para definido-OR.
C Operadores que faltan en Perl
Esto es lo que C tiene y Perl no:
- unario y
-
Dirección del operador. (Pero mira el
""
operador para tomar una referencia.) - unario *
-
Operador de dirección de desreferencia. (Los operadores de desreferenciación de prefijos de Perl se escriben:
$
,@
,%
, y&
.) - (ESCRIBE)
-
Operador de fundición tipográfica.
Operadores de cotizaciones y cotizaciones
Si bien generalmente pensamos en las comillas como valores literales, en Perl funcionan como operadores, proporcionando varios tipos de capacidades de interpolación y coincidencia de patrones. Perl proporciona caracteres de comillas habituales para estos comportamientos, pero también le ofrece una forma de elegir su carácter de comillas para cualquiera de ellos. En la siguiente tabla, un {}
representa cualquier par de delimitadores que elija.
Customary Generic Meaning Interpolates '' q{} Literal no "" qq{} Literal yes `` qx{} Command yes* qw{} Word list no // m{} Pattern match yes* qr{} Pattern yes* s{}{} Substitution yes* tr{}{} Transliteration no (but see below) y{}{} Transliteration no (but see below) <<EOF here-doc yes* * unless the delimiter is ''.
Los delimitadores sin corchetes usan el mismo carácter hacia adelante y hacia atrás, pero los cuatro tipos de corchetes ASCII (redondo, ángulo, cuadrado, rizado) todos anidan, lo que significa que
q{foo{bar}baz}
es lo mismo que
'foo{bar}baz'
Sin embargo, tenga en cuenta que esto no siempre funciona para citar código Perl:
$s = q{ if($x eq "}") ... }; # WRONG
es un error de sintaxis. los Text::Balanced
módulo (estándar a partir de v5.8, y de CPAN antes de esa fecha) puede hacer esto correctamente.
Puede (y en algunos casos, debe) ser un espacio en blanco entre el operador y los caracteres entre comillas, excepto cuando #
se utiliza como carácter de cita. q#foo#
se analiza como la cadena foo
, tiempo q #foo#
es el operador q
seguido de un comentario. Su argumento se tomará de la siguiente línea. Esto le permite escribir:
s {foo} # Replace foo {bar} # with bar.
Los casos en los que se deben usar espacios en blanco son cuando el carácter entre comillas es un carácter de palabra (lo que significa que coincide /w/
):
q XfooX # Works: means the string 'foo' qXfooX # WRONG!
Las siguientes secuencias de escape están disponibles en construcciones que se interpolan y en transliteraciones cuyos delimitadores no son comillas simples ("'"
).
Sequence Note Description t tab (HT, TAB) n newline (NL) r return (CR) f form feed (FF) b backspace (BS) a alarm (bell) (BEL) e escape (ESC) x{263A} [1,8] hex char (example shown: SMILEY) x1b [2,8] restricted range hex char (example: ESC) N{name} [3] named Unicode character or character sequence N{U+263D} [4,8] Unicode character (example: FIRST QUARTER MOON) c[ [5] control char (example: chr(27)) o{23072} [6,8] octal char (example: SMILEY) 033 [7,8] restricted range octal char (example: ESC)
- [1]
-
El resultado es el carácter especificado por el número hexadecimal entre llaves. Ver “[8]”a continuación para obtener detalles sobre qué personaje.
Solo los dígitos hexadecimales son válidos entre llaves. Si se encuentra un carácter no válido, se emitirá una advertencia y el carácter no válido y todos los caracteres subsiguientes (válidos o no válidos) entre llaves se descartarán.
Si no hay dígitos válidos entre llaves, el carácter generado es el carácter NULL (
x{00}
). Sin embargo, una llave vacía explícita (x{}
) no provocará una advertencia (actualmente). - [2]
-
El resultado es el carácter especificado por el número hexadecimal en el rango de 0x00 a 0xFF. Ver “[8]”a continuación para obtener detalles sobre qué personaje.
Solo los dígitos hexadecimales son válidos siguiendo
x
. Cuandox
va seguido de menos de dos dígitos válidos, los dígitos válidos se rellenarán con ceros. Esto significa quex7
será interpretado comox07
, y solo"x"
será interpretado comox00
. Excepto al final de una cadena, tener menos de dos dígitos válidos resultará en una advertencia. Tenga en cuenta que aunque la advertencia dice que se ignora el carácter ilegal, solo se ignora como parte del escape y se seguirá utilizando como el carácter posterior de la cadena. Por ejemplo:Original Result Warns? "x7" "x07" no "x" "x00" no "x7q" "x07q" yes "xq" "x00q" yes
- [3]
-
El resultado es el carácter Unicode o la secuencia de caracteres dada por nombre. Ver nombres de caracteres.
- [4]
-
N{U+hexadecimal number}
significa el carácter Unicode cuyo punto de código Unicode es número hexadecimal. - [5]
-
El personaje que sigue
c
se asigna a algún otro carácter como se muestra en la tabla:Sequence Value [email protected] chr(0) cA chr(1) ca chr(1) cB chr(2) cb chr(2) ... cZ chr(26) cz chr(26) c[ chr(27) # See below for chr(28) c] chr(29) c^ chr(30) c_ chr(31) c? chr(127) # (on ASCII platforms; see below for link to # EBCDIC discussion)
En otras palabras, es el carácter cuyo punto de código ha tenido 64 xor con su mayúscula.
c?
es DELETE en plataformas ASCII porqueord("?") ^ 64
es 127, y[email protected]
es NULL porque el ord de"@"
es 64, por lo que xor’ing 64 en sí mismo produce 0.También,
cX
rendimientoschr(28) . "X"
para cualquier X, pero no puede ir al final de una cadena, porque la barra invertida se analizaría como un escape de la comilla final.En las plataformas ASCII, los caracteres resultantes de la lista anterior son el conjunto completo de controles ASCII. Este no es el caso de las plataformas EBCDIC; consulte “DIFERENCIAS DEL OPERADOR” en perlebcdic para una discusión completa de las diferencias entre estas para plataformas ASCII versus EBCDIC.
El uso de cualquier otro carácter siguiendo el
"c"
además de los enumerados anteriormente, se desaconseja, y a partir de Perl v5.20, los únicos caracteres realmente permitidos son los ASCII imprimibles, menos la llave izquierda"{"
. Lo que sucede con cualquiera de los otros caracteres permitidos es que el valor se deriva mediante xor’ing con el séptimo bit, que es 64, y se genera una advertencia si está habilitado. El uso de caracteres no permitidos genera un error fatal.Para obtener controles independientes de la plataforma, puede usar
N{...}
. - [6]
-
El resultado es el carácter especificado por el número octal entre llaves. Ver “[8]”a continuación para obtener detalles sobre qué personaje.
Si se encuentra un carácter que no es un dígito octal, se genera una advertencia y el valor se basa en los dígitos octales anteriores, descartándolo y todos los caracteres siguientes hasta la llave de cierre. Es un error fatal si no hay dígitos octales.
- [7]
-
El resultado es el carácter especificado por el número octal de tres dígitos en el rango de 000 a 777 (pero es mejor no usarlo por encima de 077, consulte el párrafo siguiente). Ver “[8]”a continuación para obtener detalles sobre qué personaje.
Algunos contextos permiten 2 o incluso 1 dígito, pero cualquier uso sin exactamente tres dígitos, siendo el primero un cero, puede dar resultados no deseados. (Por ejemplo, en una expresión regular puede confundirse con una referencia inversa; consulte “Escapes octales” en perlrebackslash.) A partir de Perl 5.14, puede usar
o{}
en cambio, lo que evita todos estos problemas. De lo contrario, es mejor usar esta construcción solo para ordinales