More scalar utilities #42

Open
schwern opened this Issue Jun 19, 2009 · 13 comments

Comments

Projects
None yet
2 participants
Contributor

schwern commented Jun 19, 2009

trim (strip whitespace), ltrim, rtrim
is a number
is an integer, decimal... all the stuff from perlfaq4

is a regex

is an object/instance
is a reference

Contributor

notbenh commented Jun 20, 2009

I'll pick this one up.

Contributor

notbenh commented Jul 10, 2009

trim/ltrim/rtrim: done
is_number and friends: done

still todo:

  • is_regex
  • is_object
  • is_instance
  • is_ref
Contributor

schwern commented Jul 17, 2009

All the trims are merged in

Contributor

schwern commented Feb 28, 2010

The perlfaq4 stuff is merged in.

Contributor

notbenh commented Mar 2, 2010

Cool, thanks for finishing that stuff up. This issue is still open, so is there anything else that I should start or is this just waiting to be closed?

Contributor

schwern commented Mar 2, 2010

is a regex, object/instance, and reference didn't make it in IIRC. Neither is array, scalar, hash, glob, etc...

Contributor

notbenh commented Mar 19, 2013

So I started digging in to this one again but it seems that UNIVERSAL.pm is not the right place for this as the object is not yet an object enough to call ->mo from? Is there a better place to put things like is_instance? Or should each type (ie SCALAR, ARRAY... ) overwrite the stub with the same code?

Contributor

schwern commented Mar 20, 2013

These weren't conceived as meta methods. If they were put in like is_number are into perl5i::2::UNIVERSAL it would just be $thing->is_ref.

They probably should be meta methods, I don't think the concept existed when this issue was written, to avoid polluting the universal namespace. In that case they go into perl5i::2::Meta::Instance. Then $thing->mo->is_object will work.

I'd also suggest is_object rather than is_instance. Even though its perl5i::2::Meta::Instance, everywhere else we call them objects. Its even mo the "meta object". And "object" vs "class" is more generally understood.

Contributor

notbenh commented Mar 20, 2013

The way that I was thinking of it would be that we have both is_instance and is_object but they mean different things. In the case of $thing->is_instance('CLASS') then this should check $thing->mo->linear_isa for 'CLASS' and if no match is found then ask $thing->mo->reftype if it's 'CLASS'. This will allow us then to say that is_array is really just is_instance('ARRAY') to allow for a blessed array to still be is_array.

Then for is_ref is just a boolean check around reftype and is_object is just linear_isa[0] ne reftype .

But my complication is that this line of thinking relies completely on having mo handy, and it seems that in UNIVERSAL the value is not yet an object enough to have ->mo. Should I approach this one from another direction?

Contributor

schwern commented Mar 21, 2013

If I understand, you want is_instance to check if its an instance of a class or a reference of that type?

method is_instance($class_or_reftype) {
    return $self->isa($class_or_reftype) or ref $self->mo->reftype($class_or_reftype);
}

I'm not sure I follow your example of wanting to check that an array is an array class or an array ref. What situation would that be useful?

is_ref should be just return ref $self ? 1 : 0. is_object can use Scalar::Util::blessed. Every object is a reference, but not every reference is an object.

mo is available for everything, thanks to the magic of autoboxing.

$ perl -wle 'use perl5i::2;  say 42->mo->id'
b

And this doesn't go into perl5i::2::UNIVERSAL, calls on mo go into perl5i::2::Meta::Instance.

Contributor

notbenh commented Mar 21, 2013

Yes, though I was thinking of using linear_isa as it always goes back to UNIVERSAL even for the cases of refs because of autobox. Then is_array would still work in all cases. Or it's also completely possible that I'm 100% mistaken in both my understating of what linear_isa is in comparison to isa as well as the goal here.

As to is_object, good point about using SU::blessed, that will be far more reliable then what I had been thinking.

Lastly I think that there is still some confusion on the UNIVERSAL v Meta issue. If we look at your method of is_instance, it seems that this should exist for all the autobox classes, thus it should live in UNIVERSAL (ie $thing->is_instance('Thingie'), rather then $thing->mo->is_instance('Thingie')) But if you include such a method in UNIVERSAL, it all blows up:

Global symbol "$class_or_reftype" requires explicit package name at lib/perl5i/2/UNIVERSAL.pm line 36.
syntax error at lib/perl5i/2/UNIVERSAL.pm line 36, near "){"
Global symbol "$self" requires explicit package name at lib/perl5i/2/UNIVERSAL.pm line 37.
Global symbol "$class_or_reftype" requires explicit package name at lib/perl5i/2/UNIVERSAL.pm line 37.
Compilation failed in require at lib/perl5i/2/autobox.pm line 11.
Compilation failed in require at lib/perl5i/2/Meta/Instance.pm line 12.
BEGIN failed--compilation aborted at lib/perl5i/2/Meta/Instance.pm line 12.
Compilation failed in require at lib/perl5i/2/Meta.pm line 11.
Compilation failed in require at lib/perl5i/2.pm line 17.
BEGIN failed--compilation aborted at lib/perl5i/2.pm line 17.
Compilation failed in require at /usr/share/perl5/core_perl/parent.pm line 20.
BEGIN failed--compilation aborted at lib/perl5i/latest.pm line 9.
Compilation failed in require at t/is_instance.t line 3.
BEGIN failed--compilation aborted at t/is_instance.t line 3.

if you convert it to a sub:

sub is_instance{
  my ($self,$class_or_reftype) = @_;
  return $self->isa($class_or_reftype);
}

Then the error is now:

Can't call method "isa" on unblessed reference at lib/perl5i/2/UNIVERSAL.pm line 39.

Thus if we really want to have $thing->is_instance('Thingie') then it seems that we can not have access to mo? Is this a timing thing? Or again is this just further proof that I've missed the thought train on this one?

Contributor

notbenh commented Mar 21, 2013

Oop, I realized that I did not include the test:

#!/usr/bin/env perl

use perl5i::latest;
use Test::Most;

my $array = [];
ok $array->is_instance('ARRAY');
Contributor

schwern commented Mar 22, 2013

We worked out a couple things at the PDX Hackathon last night...

Things is in autobox don't affect blessed objects. This means putting things in perl5i::2::UNIVERSAL isn't like putting things into UNIVERSAL, which is good.

We clarified what goes into perl5i::2::UNIVERSAL and what goes into perl5i::2::Meta (ie. $foo->method vs $foo->mo->method). The former is for things which act on the data. The latter is for things which act on the thing holding the data. For example, $thing->is_number is acting on the data in $thing. $thing->mo->is_object is acting asking about $thing itself.

More practically, autoboxed methods don't work on blessed objects. A simpler way to think about it is if a method is supposed to apply to everything it should be $thing->mo->method in perl5i::2::Meta::Instance.

I'll update the wiki and put some comments in the relevant modules.

@ghost ghost assigned notbenh Mar 22, 2013

notbenh pushed a commit to notbenh/perl5i that referenced this issue Mar 26, 2013

ben hengst
resolve the missing methods from #42 seems ->isa() already does what …
…is_instance was intended to do thus I am dropping is_instance.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment