Object::Import(3pm)

πŸ“¦
version 1.006 Β· 3 versions
, in ubuntu stonking

πŸ’– Object::Import πŸ’–

okay bestie, so this is the manual page for Object::Import, a lil module from the User Contributed Perl Documentation (it's in the 3pm section, iykyk β€” that's where perl module docs live). it has one job and it does it gorgeously: importing methods of an object as functions into a package. slay. let's get into it 🫢


✨ SYNOPSIS ✨

use Object::Import $object;
foo(@bar); # now means $object->foo(@bar);

like… that's it. that's the whole vibe. foo(@bar) literally means $object->foo(@bar) now. iconic behavior. πŸ‘‘


🌸 DESCRIPTION 🌸

so here's the tea: this module lets you call methods of a certain object so much more easily by exporting them as functions to a package. the exported functions are not called as methods and they do not receive an object argument β€” instead the object is fixed (locked in, no take-backs) at the time you import them with this module. periodt.

you use the module with this syntax:

use Object::Import $object, %options;

here, $object is the object you want to import the methods from. this can be a perl object (a blessed reference) OR the name of a package that has class methods. both work, we love options πŸ’…

now, as usual, a use statement is executed at compile time, so bestie please take care not to use values that you compute only in run-time, eg.

my $object = Foo::Bar->new();
use Object::Import $object; # WRONG: $object is not yet initialized

that's a big fat nope, $object ain't even initialized yet 😭 instead, you have to create the object before you import, such as

use Object::Import Foo::Bar->new();

you can also call import in run-time, eg.

use Object::Import ();
my $object = Foo::Bar->new();
import Object::Import $object;

but in that case, you can't call the imported functions without parenthesis. the audacity of perl, honestly. πŸ™ˆ

if you don't give an explicit list of methods to export, Object::Import tries to find out what callable methods the object has and imports all of them. some methods are excluded from exporting in this case, namely:

  • any methods where exporting would overwrite a function existing in the target package
  • or would override a builtin function
  • also any methods with names that are special to perl, such as DESTROY
  • and any methods whose name starts with an underscore

this automatic search for methods is quite fragile β€” and honestly, that's the fault of the way perl OO works, not the module, so don't come for it πŸ’€ it can find subroutines that shouldn't actually be called as methods, or not find methods that can actually be called. in particular, even if you import an object from a purely object oriented module, it can find non-method subs imported from other (non-OO) modules. messy, but that's the lowdown.

if you do give a list of methods to export, Object::Import trusts you know what you mean, so it exports all those subs even if it has to replace existing subs or break something else. it said "you're the main character, i believe in you" and just went with it. πŸ”₯


✨ OPTIONS ✨

the following import options can be passed to the module. one bullet per option, no skips, we're doing all of them.

  • list => $arrayref β€” sets the list of methods to export, instead of the module deciding automatically. $arrayref must be a reference to an array containing method names. eg.
use Object::Import LWP::UserAgent->new, list =>
        [qw"get post head mirror request simple_request"];
  • target => $package_name β€” export the sub names to the given namespace. default is the package from where you call import.
  • deref => 1 β€” signals that the first import argument, instead of being the object itself, is a reference to a scalar that contains the object. the content of this scalar may later be changed, and the imported functions will be called on the new contents. (the scalar may even be filled with undef, as long as you don't call the functions at that time.) if you don't pass the list of methods explicitly, the content of the scalar at the time of the import is used for determining the methods as a template to determine the methods. if, however, you give the list of methods, the content of the scalar is not examined at the time of the import.
  • prefix => $string β€” prepends a string to the names of functions imported. this is useful if some of the method names are the same as existing subs or builtins. eg.
use Object::Import $object, prefix => "foo_";
foo_bar(); # calls $object->bar();
  • suffix => $string β€” like the prefix option, only the string is appended. (matching set, we love symmetry πŸŽ€)
  • underscore => 1 β€” consider a method for automatic inclusion even if its name starts with an underscore. such methods are normally excluded, because they are usually used as private subs.
  • exclude_methods => $hashref β€” sets a list of additional methods that are not automatically imported. the argument must be a reference to a hash whose keys are potential method names. ignored if you use the list option.
  • exclude_imports => $hashref β€” sets a list of additional sub names which the module must never use as names of imported subs. these names are thus compared not with the original method names, but the names possibly transformed by adding prefixes and suffixes. this applies even if you give an explicit list of methods to import.
  • savenames => $hashref β€” save the (unqualified) names of the functions exported by adding them as a key to a hash (the value is incremented with the ++ operator). this could be useful if you wanted to reexport them with Exporter. $arrayref must be a real reference to a hash, not an undef.
  • nowarn_redefine => 1 β€” do not warn when an existing sub is redefined. that is currently only possible if you give the list of methods to be exported explicitly with the list option, because if the module chooses automatically then it will not redefine subs.
  • nowarn_nomethod => 1 β€” suppress the warning when you try to import methods from an object you might have passed in by mistake. namely the object could be:
    • the name of a nonexistent package
    • a string that is not a valid package name
    • an unblessed object
    • or undef

such values either don't currently have any methods, or calling methods on them is impossible. that warning often indicates that you passed the wrong value to Object::Import or forgot to require a package. so like, this flag is the "shhh i know what i'm doing" button. πŸ™ˆ

  • debug => 1 β€” print debugging messages about what the module exports.

πŸ“ NOTES πŸ“

πŸ¦‹ Importing from IO handles πŸ¦‹

it is possible to use an IO handle as the object to export methods from. if you do this, you should require IO::Handle first so that the handle actually has methods. you should probably also use the prefix or suffix option in such a case, because many methods of handles have the same name as a builtin function.

the handle must not be a symbolic reference, whether qualified or unqualified, eg.

open FOO, "<", "somefile" or die;
use Object::Import "FOO"; # WRONG

you can pass a handle as a glob, reference to glob, or an IO::Handle object, so any of these would work as the object after the above open statement: *FOO, "\*FOO", *FOO{IO}. another way to pass an IO::Handle object would be like this:

use IO::File;
use Object::Import IO::File->new("somefile", "<");

πŸ’œ Changing the object πŸ’œ

the deref option deserves special mention. this option adds a level of indirection to the imported functions: instead of them calling methods on an object passed to import, the methods are called on the object currently contained by a scalar to which a reference is passed in to import. this can be useful for various reasons:

  • operating on multiple objects throughout the course of the program
  • being able to import the functions at compile time before you create the object
  • or being able to destroy the object

the first of this use is straightforward, but you may need to know the following for the other two uses.

the list of methods imported is decided at the time you call import, and will not be changed later, no matter how the object is changed or methods the object supports are changed. you thus have to do extra loops if you want to call import before the object is available. the simplest solution is to pass the list of methods you want explicitly using the list option. if for some reason you don't want to do this, you need to fill the scalar with a suitable prototype object that has all the methods of the actual object you want to use. in many cases, the package name the object will be blessed to is a suitable prototype, but note that if you do not control the module implementing the object, then that module may not guarantee what package the object will actually be blessed to: the package may depend on some run-time parameters and the details about this could change in future versions of the module. this is, of course, not specific to the deref option, but true to a lesser extent to any case when you're using Object::Import without an explicit list of methods: a future version of the module could create the methods of the class in runtime or AUTOLOAD them without declaring them, or it could add new private methods that will clash with function names you're using. nevertheless, using the classname as a prototype can be a useful trick in quick and dirty programs, or if you are in control of the implementation of the object.

now let's hear about destroying an object that may hold resources you want to free. Object::Import guarantees that if you use the deref option, it does not hold references to the object other than through the one scalar, so if you undef the contents of that scalar, the object will be freed unless there are references from somewhere else. clean. ✨

finally, there's one thing you don't want to know but i must document it for completeness: if a method called through Object::Import changes its invocant (zeroth argument), that will also change the object the imported functions refer to, whether you use the deref option or not, and will change the contents of the scalar if you use the deref option.


🌈 EXAMPLES 🌈

Okay bestie, all of these examples start from the same vibe, which is this lil declaration up top:

use feature "say";

✨ Basic usage ✨

First up, a glowingly simple one: importing class methods. πŸ’…

use Math::BigInt;
use Object::Import Math::BigInt::;
say new("0x100");

This prints 256, because Math::BigInt->new("0x100") makes a big integer that equals 256. Math is mathing ✨

Now let's peek at importing object methods instead:

use Math::BigInt;
use Object::Import Math::BigInt->new("100");
say bmul(2);
say as_hex();

This prints 200 (that's 2 multiplied by 100), then 0xc8 (that's 100 as hexadecimal). Chef's kiss πŸŽ€

πŸ¦‹ Multiple imports πŸ¦‹

Now for a more complicated one β€” this prints the leading news from the English Wikinews website:

use warnings; use strict;
use LWP::UserAgent;
use XML::Twig;
use Object::Import LWP::UserAgent->new;
my $response = get "http://en.wikinews.org/wiki/Special:Export?".
    "pages=Template:Lead_article_1&limit=1";
import Object::Import $response;
if (is_success()) {
    use Object::Import XML::Twig->new;
    parse content();
    for my $parmname (qw"title summary") {
        first_elt("text")->text =~ /\|\s*$parmname\s*=([^\|\}]+)/ or die;
        print $1;
    }
} else {
    die message();
}

For example, as the author was writing this (2010-09-05), this outputs:

Magnitude 7.0 earthquake hits New Zealand

An earthquake with magnitude 7.0 occurred near South Island, New
Zealand at Saturday 04:35:44 AM local time (16:35:44 UTC). The
earthquake occurred at a depth of 16.1 kilometers (10.0 miles). The
earthquake was reported to have caused widespread damage and power
outages. Several aftershocks were also reported.

So in there, get points at the useragent object; is_success, content and message point at the response object (and honestly those must be called with a parenthesis 🫠); while parse and first_elt point at the twig object.

Not to be dramatic but this is not a good example to follow. It's quite fragile, and not only because of the simple regex used to parse out the right parts β€” it's also because if a new sub gets added to a future version of the LWP::UserAgent or HTTP::Response classes, those new subs might suddenly get imported and would shadow the methods we're supposed to import later. πŸ’€

🌸 Suffix 🌸

Now let's see an example of using a suffix:

use File::Temp;
use Object::Import scalar(File::Temp->new()), suffix => "temp";
printtemp "hello, world\nhidden";
seektemp 0, 0;
print getlinetemp;
say filenametemp;

Here we need the suffix because print and seek are names of builtin functions. Can't be out here shadowing the builtins, no ma'am 😭

πŸ’– Creating the object later πŸ’–

Let's see how we can import methods before we create an object:

use Math::BigInt;
our $number;
use Object::Import \$number, deref => 1, list => ["bmul"];
sub double { bmul 2 }
$number = Math::BigInt->new("100");
say double;

This will output 200. Notice how here we're using the bmul function without parenthesis, so we must import it at compile time for the code to parse correctly β€” but the object itself isn't created till later. Time zones of the code, iykyk ⏳

🧚 Prototype object 🧚

This code is the same as the one above, except that instead of supplying a list of methods, we use a prototype object, namely the Math::BigInt package. At least one of the two is needed, for otherwise Object::Import would have no way to know what methods to import.

use Math::BigInt;
our $number;
use Object::Import \($number = Math::BigInt::), deref => 1;
sub double { bmul 2 }
$number = Math::BigInt->new("100");
say double;

πŸ‘‘ Exporting to other package πŸ‘‘

This example shows how to export to a different namespace. This is useful if you want to write your own sugar module that provides a procedural syntax:

package My::Object::DSL;
use Object::Import;
use My::Object;

sub import {
    my ($class, %options);
    if (@_ == 2) {
        ($class, $options{ name }) = @_;
    } else {
        ($class, %options) = @_;
    };
    my $target = delete $options{ target } || caller;
    my $name = delete $options{ name } || '$obj';
    my $obj = My::Object->new(%options);

    $name =~ s/^[\$]//
        or croak 'Variable name must start with $';
    {
        no strict 'refs';
        *{"$target\::$name"} = \$obj;
        # Now install in $target::
        import Object::Import \${"$target\::$name"},
                              deref => 1,
                              target => $target;
    }
}

You can use the module My::Object::DSL like this:

use My::Object::DSL '$obj';

And if you want to pass more options, you can do:

use My::Object::DSL name => '$obj', foo => 'bar';

Implementing a small ::DSL module instead of using Object::Import directly has the advantage that you can add defaults in DSL.pm. Bestie, that's the whole reason β€” defaults, defaults, defaults ✨


πŸ”₯ SEE ALSO πŸ”₯

  • Class::Exporter
  • Scope::With
  • Sub::Exporter
  • Acme::Nooo

πŸ’€ BUGS πŸ’€

Please report bugs using the CPAN bug tracker (under the distribution name Object-Import), or, failing that, to corion@cpan.org. Spill the tea to the bug tracker first, fr fr πŸ›


🫢 CREDITS 🫢

The primary author and maintainer of this module is Zsban Ambrus ambrus@math.bme.hu. Some of the code was written by Max Maischein, who also gave the motivation to turn a prototype into the full module you see. Thanks to exussum0 for the original inspiration. πŸ‘

The module is maintained by Max Maischein since 2018.


πŸŽ€ COPYING πŸŽ€

Copyright (C) Zsban Ambrus 2010

This program is free software: you can redistribute it and/or modify it under the terms of either the GNU General Public License version 3, as published by the Free Software Foundation; or the Artistic License which comes with perl.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

A copy of the GNU General Public License can be found in the source tree of this module under the name GPL, or else see http://www.gnu.org/licenses/. A copy of the Artistic License can be found in the source tree under the name ARTISTIC, or else see http://search.cpan.org/~rjbs/perl-5.16.1/pod/perlartistic.pod.


And that's a wrap, bestie! πŸ’œ This whole page is from the perl v5.40.1 days β€” dated 2026-01-14 β€” and if you ever forget which page you're on, it's Object::Import(3pm). Slay, go import something iconic 🌟

πŸ“¦ where this page comes from