porting Ruby's String class to Perl

ethan on 2003-08-09T07:59:32

Not that Perl would be lacking string manipulation facilities, but this new feature proposal for (allegedly) perl5.10 simply cries for rubyisms::String:



use autobox SCALAR => 'rubyisms::String';

print " bla "->strip;

my $foo = "bAR"; $foo->capitalizeI; print $foo;


Due to different lexer rules in Ruby I had to find a different nomenclature for string.strip! so I chose $string->stripI with 'I' being mnemonic for 'in-place' while maintaining some visual similarity to '!'.

So far done are capitalize, capitalizeI, strip, stripI and center. This will take another couple of days since it's being done in XS. After that I can finally run some benchmarks and see whether the XS approach makes up for some of the performance hits introduced by autobox (which I haven't yet benchmarked, either, so they might not even be severe at all).

For those being adventurous enough (and curious about how it feels like to have everything act like an object), grab perl5.8.1-RC4 and autobox from the CPAN, apply the patch, compile and have FUNNNNNN!


See CPAN

djberg96 on 2003-08-09T14:01:41

Too some degree that was my intention with Set::Array, Set::String and Set::Hash. I also used the Want module to make method chaining more sensical, passing $self if chained, or a value otherwise.

Rather than using method vs methodI, I chose to use context to determine whether or not the receiver was modified, which seemed more Perlish.

Re:See CPAN

ethan on 2003-08-09T15:43:16

My first intention was to really duplicate Ruby's interface. On second thought, this might not be a good idea. One reason for that is that I am not yet sure whether autobox.pm is powerful enough. Also, I don't know what happens when you do a string.strip!.capitalize! in Ruby (that is, will string be capitalized and stripped in-place? If so, can this be done with autobox at all?)

The main problem here is to determine whether something feels Perlish or not: Perl so far had no primitive objects and subsequently there is no experience with it. So far I can say that this new interface feels kind of odd with Perl...but not unpleasant.

Scalar::Properties does some of that

marcel on 2003-08-10T00:01:28

Have you seen Scalar::Properties?

Seems to do some of what you propose.

ObPlug.

Marcel

Re:Scalar::Properties does some of that

ethan on 2003-08-10T05:48:51

No, actually I hadn't seen it. It seems to result in the same interface. Two differences though: One is the implementation. You use constant overloading and thus turn things into real objects. autobox on the other hand wont ever bless something. It invokes the method directly on the primitives (and thus wont suffer from the slowdown caused by blessed referents). Btw, it is lexically scoped, so it can be turned on and off selectively for blocks.

Secondly, Scalar::Properties comes with its own methods whereaus in case of autobox you add them to the classes SCALAR, HASH and ARRAY yourself. This is both more extensible and easier to use from XS since the extension subroutines simply receive an ordinary (non-blessed) SV* as first argument.

The disadvantage of autobox on the other hand is that you need to patch perl itself, at least until it finds its way into perl5.10 (which isn't yet clear at all).

Module name

ioannis on 2003-08-10T07:12:02

Perhaps you might consider changing the module name to String::Ruby to force consistency with String::Rexx (I am the author). For other more specific ruby features related to strings, the naming could in sync with String::RexxParse, String::RexxStack (which will scheduled to reach cpan later next week). This way, i suspect it will be easier for visitors to find your module when they search for "String". Just a suggestion.

Re:Module name

ethan on 2003-08-10T07:32:36

You are right, good suggestion. I don't like rubyisms::String very much either...I chose it because of Simon Cozen's rubyisms module.

Hmmh, is there a rule that lexically scoped module usage has to relate to pragmata? I just implemented the import() and unimport() semantics that allow


            use String::Ruby;
            print "foo"->center(10);
            {
                no String::Ruby;
                print "foo"->center(10); # fatal error
            }


I guess there's nothing wrong with that even though the module is still rather pragmatic.