2009-11-02 16 views
11

¿Por qué Perl no soporta el operador normal [] para indexar una cadena?¿Por qué Perl no admite el operador normal [] para indexar una cadena?

Casi todos los principales lenguajes de programación admiten este operador, especialmente los otros dos 'P': Python y PHP. Además, creo que debería ser fácil implementar esta pequeña sintaxis. Además, como la filosofía del lenguaje de programación de Perl, tan vago como podríamos, ¿por qué nos molestamos en usar una función para indexar una cadena?

¿Perl 6 es compatible con esta sintaxis?

+2

No es una característica. Es solo sintaxis. – postfuturist

+4

No hay nada "normal" en '[]'. No solo eso, sino '[]' puede o no implementarse como una función a pesar de su sintaxis (por ejemplo, en Ruby '[]' es en realidad un método). – rfunduk

+3

Nota al margen: no es necesario que Perl, Python y PHP compartan funciones o sintaxis alguna. Esos tres idiomas tienen una sintaxis muy diferente, una semántica muy diferente y objetivos de diseño muy diferentes.Si espera que sean iguales, entonces se encontrará con una gran decepción. (Por ejemplo, en Haskell, el operador para extraer el enésimo carácter de una cadena, o el enésimo elemento de cualquier lista, es '$$'. Nadie se queja de que Haskell no use '[]' para ese propósito ... .) –

Respuesta

45

Me gustan todas las respuestas hasta ahora, pero la verdadera respuesta es "porque Larry lo quiere así". De Verdad. A Larry se le ocurrió una serie de modismos y herramientas que funcionaban para él, y él compartió eso con nosotros en la forma de Perl. Si no piensas como Larry piensa, entonces hay muchas otras herramientas para usar. No necesitamos que todo el mundo use Perl ... solo la gente que "lo entiende" como lo hace Larry.

+0

Sí, pero ¿cuál fue el razonamiento de Larry? Tal vez tienes alguna idea? –

18

¿Desea indexar por bytes, caracteres o grafemas?

Es por esto que en Perl 6 length is "banned", en lugar de utilizar uno de los siguientes:

  • bytes
    exactamente un byte a la vez
  • chars
    Dependiendo del texto de origen esto puede ser una un solo byte, o varios bytes.
  • graphs
    Esto es similar a los caracteres, pero combina varios caracteres "combinados".

Si realmente queremos que usted puede hacer algo similar, usando split.

(split '', $str)[$index]; 

Probablemente es mejor utilizar sólo substr sin embargo.

substr $str, $index, 1; 
+0

He escrito '(split //, $ str) [$ index]' ya que eso evita construir una lista anónima innecesaria, pero ambas se ven algo extrañas, ¿no? 'substr ($ str, $ index, 1)' (o '$ str.substr ($ index, 1)', en Perl 6) es probablemente el mejor, en cuanto a legibilidad. – ephemient

+1

Para aquellos confundidos por el "undef dividido", split puede tomar una expresión regular en // - notación (por ejemplo, 'split/foo /') o cualquier expresión que deba interpretarse como una expresión regular (por ejemplo 'split 'fo' '). "o" '). Undef se promueve a una cadena vacía y se compila como una expresión regular, produciendo el mismo resultado que 'split //', excepto con una advertencia de '' Uso del valor no inicializado ''. (La otra diferencia es que tengo que intentar compilar la expresión regular para cada vez que se ejecuta la división en lugar de solo una vez). – ysth

+0

Utilicé 'split '', ...' aquí en lugar de 'split //, ... 'debido a problemas con el marcador de código. –

7

En Perl, las cadenas son escalares y, por lo tanto, no son subscripbles por defecto. Puede usar funciones como substr() o index() para acceder a caracteres específicos en una cadena.

A menos que Perl 6 rompa con este concepto al cambiar cadenas por una matriz de caracteres, no creo que haya ningún cambio en esto.

+0

Bueno, en Perl 6, los escalares son objetos, por lo que podría haber un método que haga lo mismo. –

+0

Estoy abierto a cambios siempre que no rompan todas las cosas existentes;) – Shirkrin

+0

Probablemente podría hacerse con algo de magia usando 'autobox' y anulando el operador' [] '. – Ether

12

Perl tiene una forma de indexar una cadena con index o substr. Es compatible con la operación. Que lo haga con otra sintaxis no debería importar. Hay una razón por la que tenemos más de un lenguaje de programación. :)

No diría que [] es un operador "normal". Estoy seguro de que las personas pueden enumerar muchos idiomas que tampoco lo hacen.

+0

Ayudaría agregar una línea que describa la "otra sintaxis" –

+0

Hay algo irracionalmente irónico en que alguien se queje de que la respuesta de Brian sea breve en detalles :) Editaré la respuesta de Brian para incluir la sintaxis sugerida en el comentario a continuación. – DVK

+0

... Por cierto, es irónico que Brian parezca ser el editor más prolífico de los Perl Qs y As de otros, añadiendo detalles aclaratorios con bastante frecuencia. – DVK

23

El uso de [] para indexar en una cadena es un efecto secundario de la forma en que muchos lenguajes de programación tratan cadenas: como matrices de caracteres (o caracteres anchos, en el caso de Unicode). En Perl, las cadenas son entidades de primera clase. Perl proporciona una gran cantidad de formas para trabajar con cadenas enteras como un valor único. Si intenta indexar en una cadena, probablemente esté haciendo algo mal. (por ejemplo, escribir C en Perl en lugar de usar expresiones idiomáticas Perl). Para los casos en los que realmente necesita indexar en una cadena, use substr.

+5

Que una cadena sea una entidad de primera clase (a diferencia de una simple matriz de caracteres) no significa que no se pueda tratar sintácticamente como una matriz. Ver Java, C# y Delphi, por ejemplo. –

9

Si realmente desea tratar los escalares como objetos, puede usar autobox.

No consumo autobox, pero esto debería funcionar:

my $indexed = ('foo'->list)[1]; 

autobox tiene ganchos para la definición de objetos a utilizar para envolver diversos tipos de datos.

Por lo tanto, si realmente, realmente lo desea, usted debería ser capaz de utilizar autobox para crear su propia clase string que permitirá código como este:

my $indexed = 'foo'->[3]; 

Por lo tanto, creo que la respuesta a su pregunta , "¿Por qué Perl no tiene [] sintaxis para la indexación de cadenas?" es "Nadie lo ha querido lo suficiente como para implementarlo".

En cuanto a Perl 6, no he seguido lo suficiente para dar una respuesta más allá: "Si no está presente y realmente lo quieres, podrás agregarlo tú mismo".

+2

No está presente en Perl 6, pero creo que debería ser capaz de definir un 'método múltiple postcircumflex: <[ ]> (Str, Int)' (aunque no puedo verificarlo porque Rakudo aún no lo admite). – ephemient

7

¿Cuál es el nombre de la cadena? Es escalar, por lo que el sigilo obviamente será $. El resto sigue los estándares estándar de nomenclatura variable; digamos $abc.

my $abc = 'A string'; 

Como sigilos significan contexto s de la expresión, y no son una parte del nombre, tenemos una colisión.

my $def = $abc[2]; 

no es la tercera letra del escalar $abc, pero el tercer elemento de una matriz - compartiendo el mismo símbolo (pero con un diferente sigilo): @abc.

De modo que esa expresión, que probablemente se diseñó pronto para la resolución de símbolos tipo script, ya tiene un significado asignado.

Por supuesto, como respuesta de Brad señala, sólo puede haber un sentido a que si hacemos suposiciones implícitas en cuanto a lo que hace que una parte de la cadena de un "elemento" en la "lista". Cuantas más codificaciones tengas que usar, peores esas suposiciones predeterminadas funcionan.

Usted puede encontrar una sintaxis prefiere más el uso de autobox:

$string->ch(2); 

(que tendría que escribir ch sí mismo.) Pero eso es necesariamente más detallado que simplemente poner en el soporte de cuerdas.

Cuestiones relacionadas