tags:

views:

581

answers:

7

Why doesn't Perl support the normal [] operator to index a string? Almost all major programming languages support this operator,esp the other two 'P': python and php.Moreover,I do think it should be easy to implementate this little syntax.Also,as the philosophy of the perl programming language -- as lazy as we could,so why do we bother to use function to index string?

Will Perl 6 support this syntax?

thanks.

+13  A: 

Do you want to index by bytes, characters, or graphemes?

This is why in Perl 6 length is "banned", Instead you use one of the following:

  • bytes
    Exactly one byte at a time
  • chars
    Depending on the source text this can be a single byte, or several bytes.
  • graphs
    This is similar to chars, but combines multiple "combining" characters together.


If you really want it you can do something similar, using split.

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

It is probably better to just use substr though.

substr $str, $index, 1;
Brad Gilbert
I'd have written `(split //, $str)[$index]` as that avoids building an unnecessary anonymous list, but both look kinda odd, don't they? `substr($str, $index, 1)` (or `$str.substr($index, 1)`, in Perl 6) is probably the best, readability-wise.
ephemient
For those confused by the "split undef", split can take a regular expression in //-notation (e.g. `split /foo/`) or any expression that should be interpreted as a regular expression (e.g. `split "fo"."o"`). The undef is promoted to an empty string and compiled as a regular expression, producing the same result as `split //`, except with a "Use of uninitialized value" warning. (The other difference is perl having to try to compile the regular expression for each time the split is executed instead of just once.)
ysth
+7  A: 

In Perl, strings are scalars and thus are not subscriptable by default. You can use functions like substr() or index() to access specific characters in a string.

Unless Perl 6 breaks with this concept by changing strings to an array of char's I don't think there will be any changes to this.

Shirkrin
Well, in Perl 6, scalars are objects, so there could very well be a method that does the same thing.
brian d foy
I'm open for changes as long as they don't break all existing stuff ;)
Shirkrin
It could probably be done with some magic using `autobox` and overriding the `[]` operator.
Ether
..and now I see that daotoad has written up a solution doing exactly that. :)
Ether
+11  A: 

Perl has a way to index a string with index or substr. It supports the operation. That it does it with another syntax shouldn't matter. There's a reason we have more than one programming language. :)

I wouldn't say that [] is a "normal" operator. I'm sure people can list many languages that don't do that either.

brian d foy
It would help to add a line that describes the "another syntax"
Murali VP
There's something wickedly ironic about someone complaining about brian's answer being short on details :)I will edit brian's answer to include the syntax suggested in the comment below.
DVK
... BTW, the reason it's ironic is brian seems to be the most prolific editors of others' Perl Qs and As, adding clarifying details quite often.
DVK
I rolled back the edit and linked to substr instead. There weren't more details because the question wasn't asking how to index a string but why Perl didn't use a particular syntax.
brian d foy
I have noticed the same brian habitually rolling back his answer once he sees a better answer from someone else!
Murali VP
I even delete some of my answers. :)
brian d foy
By the way, good writing comes from good editing. Since the goal of SO is to provide good info via Google, I'm constantly editing my own answers.
brian d foy
Appreciate the constant edits, thanks for providing free answers, but edits done right after someone else posts a better answer means something else. Of course, it earns some reputation, hope that is not the goal.
Murali VP
The only goal is correct information. SO rep is meaningless to me; I can't trade it for vacations, food, or new digital cameras. :) Once you get past 10k rep, there aren't any new levels to unlock anyway.
brian d foy
+20  A: 

Using [] to index into a string is a side effect of the way many programming languages treat strings: as arrays of characters (or wide characters, in the case of Unicode). In Perl, strings are first-class entities. Perl provides a wealth of ways for working with whole strings as a single value. If you're trying to index into a string you're probably doing something wrong. (e.g. writing C in Perl rather than using Perl idioms.) For the cases where you really do need to index into a string, use substr.

Michael Carman
That a string is a first-class entity (as opposed to a simple array of characters) doesn't mean it can't be treated syntactically as an array. See Java, C#, and Delphi, for instance.
Rob Kennedy
+8  A: 

If you really want to treat scalars as objects, you can use autobox.

I don't use autobox, but this should work:

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

autobox has hooks for defining objects to use for wrapping various data types.

So, if you really, really want it, you should be able to use autobox to create your own string class that will allow code like this:

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

So, I think the answer to your question, "Why doesn't Perl have [] syntax for string indexing?" is "Nobody has wanted it enough to implement it."

As to Perl 6, I haven't followed closely enough to give an answer beyond, "If it isn't present and you really want it, you will be able to add it yourself."

daotoad
It isn't present in Perl 6, but I think you should simply be able to define a `multi method postcircumflex:<[ ]>(Str, Int)` (though I can't check since Rakudo doesn't support it yet).
ephemient
+6  A: 

What's the name of the string? It's scalar, so the sigil will obviously be $. The rest of it follows standard variable naming standards; let's say $abc.

my $abc = 'A string';

As sigils signify contexts of the expression, and are not a part of the name, we have a collision.

my $def = $abc[2];

is not the 3rd letter of the scalar $abc, but the third element from an array--sharing the same symbol (but with a different sigil) : @abc.

So that expression, which was probably designed early for script-like symbol resolution, already has a meaning assigned to it.

Of course, as Brad's answer points out, there can only be a meaning to that if we make implicit assumptions as to what makes a part of the string an "item" in the "list". The more encodings you have to use, the worse those default assumptions work.

You might find a syntax you prefer more using autobox:

$string->ch( 2 );

(You would have to write ch yourself.) But that is necessarily more verbose than simply putting bracket's onto strings.

Axeman
+25  A: 

I like all the answers so far, but the real answer is, "because Larry wants it that way". Really. Larry came up with a set of idioms and tools that worked for him, and he shared that with us in the form of Perl. If you don't think the way Larry thinks, then there are plenty of other tools to use. We don't need the whole world using Perl... just the people who "get it" the way Larry does.

Randal Schwartz
Why was this downvoted? This is a completely correct answer, by someone who knows what he's talking about.
Daniel Pryden