Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

PerlMagick and Moo

3 views
Skip to first unread message

Rick Leir

unread,
Jul 20, 2015, 11:45:02 AM7/20/15
to mo...@perl.org
Hi everyone,

I have been working on a web service for GM PerlMagick, and Moo was suggested. The GM object is kept across requests, but the image memory is freed (question below). Here is what it looks like:
package Something::Magick;

use Graphics::Magick;

use Dancer::Core::Types; # brings helper for types
use MooX::Types::MooseLike::Base; # InstanceOf
use MooX::Types::MooseLike;

# Moo def must follow other defs.
use Moo;
with 'MooX::Singleton';

has image => (
    is => 'rw',
    isa => InstanceOf['Graphics::Magick'],
    lazy => 1,
    builder => '_build_image'
);
# The lazy attribute says to Moo that this attribute will be built (initialized)
# only when called the first time. It means that the connection to GmImage won't be opened until necessary.

sub _build_image {
    my ($self) = @_;
    Graphics::Magick->new( );
}
sub BUILD {
    my ($self) = @_;
    $self->image( Graphics::Magick->new( ));
}

sub do_sequence {
    my $self = shift;
    my @seq = shift || 1;

    my $Arrayofhashes = \$seq[0][0];
    my $sizeminus1 = @$$Arrayofhashes - 1; #++++++++++++++ 3

    for my $i ( 0 .. $sizeminus1 ) {
        my $href = $seq[0][0][$i];      

        my $opname;
        my $filepath;
        my $gmparms;
        while( my ($k, $v) = each %$href ) {
.... sanitize input ..
           if( $k eq 'op') {
                $opname = $v;
            }
            elsif( $k eq 'file') {
                $v =~ s/^\/+//;  # remove any leading /
                $filepath = $v;
            }
            elsif( $k eq 'parms') {
                $gmparms = $v;
            }
        }
..
               if( $opname eq 'Read') {
                    my $status = $self->image->Read( $absolute);
                    warn "$status" if "$status";
                } elsif( $opname eq 'Write') {
                    my $status = $self->image->Write( $absolute);
                    warn "$status" if "$status";
                }
  ...
           # some op other than read,write
               # invoke it
                my $status = $self->image->$opname( $gmparms);
                warn "$status" if "$status";
            }

    # delete all the images but retain the Graphics::Magick object
    # @$image = ();  no
    # @self->image = ();  no
    # @{self->image} = ();  no

    my $i = 0;
#    while (defined ($self->image->[$i])) {
    while ( $i < 10) {
        if (defined ($self->image->[$i])) {
            undef ($self->image->[$i]);
            print "======== undef $i\n";
        }
        $i++;
    }
}
My question is how can you delete all the images but retain the Graphics::Magick object? I do not want to use the undef loop above. With normal perlmagick, you would say
  @$image = ();
( http://www.graphicsmagick.org/perl.html )

Should I learn more about Perl XS?  TIA
--
Rick

Rick Leir

unread,
Jul 20, 2015, 1:15:02 PM7/20/15
to mo...@perl.org

On Mon, Jul 20, 2015 at 12:42 PM, Karen Etheridge <pe...@froods.org> wrote:

    my $image = $self->image;
    @$image = ();

Thanks Karen!!

--
Rick Leir
Developer, Canadiana.ca

Karen Etheridge

unread,
Jul 20, 2015, 5:00:02 PM7/20/15
to Rick Leir, mo...@perl.org
My question is how can you delete all the images but retain the Graphics::Magick object? I do not want to use the undef loop above. With normal perlmagick, you would say
  @$image = ();

It's still just Perl -- how you got the image object is irrelevant. It's still a reference and you can operate on it as normal:

    my $image = $self->image;
    @$image = ();

However, I'm shocked that there isn't an API for this. Operating on the reference directly is pretty gross.


   

Kent Fredric

unread,
Jul 20, 2015, 5:30:03 PM7/20/15
to Rick Leir, mo...@perl.org
On 21 July 2015 at 03:35, Rick Leir <richar...@canadiana.ca> wrote:
> My question is how can you delete all the images but retain the
> Graphics::Magick object? I do not want to use the undef loop above. With
> normal perlmagick, you would say
> @$image = ();
> ( http://www.graphicsmagick.org/perl.html )
>
> Should I learn more about Perl XS? TIA


Q) What value is there in persisting the GM object across uses? Why do
you need to do this?

Without good reason, I would take the advice in the Linked article,
and just `undef` the GM object.

The natural way of doing this in Moo would be to use a clearer

https://metacpan.org/pod/Moo#has

#{

Takes a method name which will clear the attribute.

If you set this to just 1, the clearer is automatically named
clear_${attr_name} if your attribute's name does not start with an
underscore, or _clear_${attr_name_without_the_underscore} if it does.
This feature comes from MooseX::AttributeShortcuts.

#}

That way, when you're done, you just call

$self->_clear_image;

And if you need an image later, a new one will be constructed by the builder.


--
Kent

KENTNL - https://metacpan.org/author/KENTNL

Rick Leir

unread,
Jul 21, 2015, 9:00:12 AM7/21/15
to Kent Fredric, mo...@perl.org
On Mon, Jul 20, 2015 at 5:13 PM, Kent Fredric <kentf...@gmail.com> wrote:
On 21 July 2015 at 03:35, Rick Leir <richar...@canadiana.ca> wrote:
> My question is how can you delete all the images but retain the
> Graphics::Magick object? I do not want to use the undef loop above. With
> normal perlmagick, you would say
>   @$image = ();
> ( http://www.graphicsmagick.org/perl.html )
>
> Should I learn more about Perl XS?  TIA


Q) What value is there in persisting the GM object across uses? Why do
you need to do this?
This is for a web service, so I want to reduce latency by keeping the GM object. We get at it using 'instance', not 'new'. And reclaiming image memory is important.
 

Without good reason, I would take the advice in the Linked article,
and just `undef` the GM object.

The natural way of doing this in Moo would be to use a clearer

https://metacpan.org/pod/Moo#has

#{

Takes a method name which will clear the attribute.

If you set this to just 1, the clearer is automatically named
clear_${attr_name} if your attribute's name does not start with an
underscore, or _clear_${attr_name_without_the_underscore} if it does.
This feature comes from MooseX::AttributeShortcuts.

#}

That way, when you're done, you just call

 $self->_clear_image;

And if you need an image later, a new one will be constructed by the builder.
Thanks for explaining 'clearer'.
cheers -- Rick
0 new messages