Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Re: Creating packages on the fly

by vkon (Curate)
on Jun 06, 2006 at 08:42 UTC ( [id://553763]=note: print w/replies, xml ) Need Help??


in reply to Creating packages on the fly

This file from Tcl::Tk CPAN distribution has many in common with your questions:
  • its a part of perl module to deal with external GUI library
  • it creates required widgets on the fly
  • it heavily uses AUTOLOAD and brings into existance widget's package where newborn widgets of that class will be blessed

However its not necessary to look into much detail, because actually in case of Tcl::Tk wdiget's package is simple and there is some stub string which is "eval"-ed to create package.

Here are excerpts from code:

$Tcl::Tk::VTEMP = <<'EOWIDG'; package Tcl::Tk::Widget::[[widget-repl]]; use vars qw/@ISA/; @ISA = qw(Tcl::Tk::Widget); sub DESTROY {} # do not let AUTOLOAD catch this method sub AUTOLOAD { print STDERR "<<@_>>\n" if $Tcl::Tk::DEBUG > 2; $Tcl::Tk::Widget::AUTOLOAD = $Tcl::Tk::Widget::[[widget-repl]]::AU +TOLOAD; return &Tcl::Tk::Widget::AUTOLOAD; } 1; print STDERR "<<starting [[widget-repl]]>>\n" if $Tcl::Tk::DEBUG > 2; EOWIDG
and then
# here we create Widget package, used for both standard cases like # 'Button', 'Label', and so on, and for all other widgets like Baloon # TODO : document better and provide as public way of doing things? my %created_w_packages; # (may be look in global stash %:: ?) sub create_widget_package { my $widgetname = shift; _DEBUG(2, "AUTOCREATE widget $widgetname (@_)\n") if DEBUG; unless (exists $created_w_packages{$widgetname}) { _DEBUG(1, "c-PACKAGE $widgetname (@_)\n") if DEBUG; $created_w_packages{$widgetname} = {}; die "not allowed widg name $widgetname" unless $widgetname=~/^\w+$ +/; # here we create Widget package my $package = $Tcl::Tk::VTEMP; $package =~ s/\[\[widget-repl\]\]/$widgetname/g; eval "$package"; die $@ if $@; # Add this widget class to ptk_w_names so the AUTOLOADer properly # identifies it for creating class methods $widgetname = quotemeta($widgetname); # to prevent chars corruptin +g regexp $ptk_w_names .= "|$widgetname"; } }

Actually it could be implemented without any string-eval, (moving CODE to some package, and it will be autocreated), but I decided to go easy way, because it was safe and efficient in this particular case.

Replies are listed 'Best First'.
Re^2: Creating packages on the fly
by Jouke (Curate) on Jun 06, 2006 at 09:01 UTC
    I may be overlooking something, but how does that create packages that the code doesn't know about yet on the fly?

    Maybe I need to be clearer:

    Wx provides Wx::Window. Let's say that I'm going to use the namespace Jouke:: and my Wx::Window subclass would become Jouke::Wx::Window. I don't want to have a predefined list of classes I want to subclass under Jouke::, but whenever the main program calls Jouke::Wx::Window->new() it should be able to identify if Wx::Window->new can be called, and if so, subclass it as Jouke::Wx::Window, and add functionality to it.

    The only part I'm having trouble with, is having a mechanism that catches every call to Jouke::Foo->whatever_method() without having to define Jouke::Foo in advance.


    Jouke Visser
    Using Perl to enable the disabled: pVoice
      you're right, Jouke::Foo->whatever_method() isn't covered in my example.

      Here is one that do:

      sub UNIVERSAL::AUTOLOAD { print STDERR "[[@_]]"; } package main; Jouke::Foo->whatever_method();
      outputs
      D:\TESTS\tperl>perl -w autocr.pl [[Jouke::Foo]]

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://553763]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (2)
As of 2024-04-20 03:58 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found