A variable within an Inline use statement

Discussion in 'Perl Misc' started by Thomas, Aug 26, 2008.

  1. Thomas

    Thomas Guest

    The following code works for me at the beginning of my own module which
    uses Inline C 0.44:

    use Inline (C => 'DATA',
    LIBS => 'foo.lib',
    BUILD_NOISY => 1,
    FORCE_BUILD => 1,
    );

    However, this variant:

    my $lib_path = 'foo.lib';
    use Inline (C => 'DATA',
    LIBS => $lib_path,
    BUILD_NOISY => 1,
    FORCE_BUILD => 1,
    );

    does not. It runs, but the string 'foo.lib' is not given as a library to
    Inline's make process so that I end up with an error "unresolved
    externals" when linking the DLL Inline creates as glue code. So a
    literal string is fine in that particular context, a variable is not.
    This is probably a basic language understanding problem of mine and has
    less to do with the Inline module, but I can't figure this one out alone.
     
    Thomas, Aug 26, 2008
    #1
    1. Advertising

  2. Thomas <> writes:

    > However, this variant:
    >
    > my $lib_path = 'foo.lib';
    > use Inline (C => 'DATA',
    > LIBS => $lib_path,
    > BUILD_NOISY => 1,
    > FORCE_BUILD => 1,
    > );
    >
    > does not.


    Use statements are handled at compile time while you assignment is
    executed at run time. That means tha you $lib_path variable gets
    assigned after you have used Inline.pm.

    The solution is to wrap you assignment in a BEGIN block.

    //Makholm
     
    Peter Makholm, Aug 26, 2008
    #2
    1. Advertising

  3. Thomas

    Ben Morrow Guest

    Quoth Thomas <>:
    > The following code works for me at the beginning of my own module which
    > uses Inline C 0.44:
    >
    > use Inline (C => 'DATA',
    > LIBS => 'foo.lib',
    > BUILD_NOISY => 1,
    > FORCE_BUILD => 1,
    > );
    >
    > However, this variant:
    >
    > my $lib_path = 'foo.lib';
    > use Inline (C => 'DATA',
    > LIBS => $lib_path,
    > BUILD_NOISY => 1,
    > FORCE_BUILD => 1,
    > );
    >
    > does not. It runs, but the string 'foo.lib' is not given as a library to
    > Inline's make process so that I end up with an error "unresolved
    > externals" when linking the DLL Inline creates as glue code. So a
    > literal string is fine in that particular context, a variable is not.
    > This is probably a basic language understanding problem of mine and has
    > less to do with the Inline module, but I can't figure this one out alone.


    'use' statements are executed at compile time, but assignments are not
    executed until runtime. This means that when the 'use Inline' line is
    executed, $lib_path doesn't yet have a value.

    There are three ways around this. By far the neatest is to use a
    constant instead of a variable, as 'use constant' lines are also
    executed at compile time:

    use constant LIB_PATH => 'foo.lib';

    use Inline C => 'DATA',
    LIBS => LIB_PATH,
    ...;

    but note that the expression in the 'use constant' line must *also* be
    known at compile time, so if you need to calculate it you will need
    something else.

    The second is to use Inline->bind instead of 'use Inline':

    use Inline;

    my $lib_path = 'foo.lib';

    Inline->bind(C => 'DATA', LIBS => $lib_path, ...);

    but that has the disadvantage that the compiled functions won't be known
    at compile time, so you will have to call them with parens. You also
    can't use this if you are writing an installable module based on Inline:
    see the Inline docs for details.

    The third, which is ugly but flexible, is to perform the assignment in a
    BEGIN block. Note that the 'my' has to come *outside* the BEGIN block,
    as otherwise the variable is only scoped to the block:

    my $lib_path;
    BEGIN { $lib_path = 'foo.lib' }

    use Inline C => 'DATA',
    LIBS => $lib_path,
    ...;

    Ben

    --
    I must not fear. Fear is the mind-killer. I will face my fear and
    I will let it pass through me. When the fear is gone there will be
    nothing. Only I will remain.
    Frank Herbert, 'Dune'
     
    Ben Morrow, Aug 26, 2008
    #3
  4. Thomas

    sisyphus Guest

    On Aug 26, 6:05 pm, Thomas <> wrote:
    > The following code works for me at the beginning of my own module which
    > uses Inline C 0.44:


    <plug>
    If you're interested, InlineX::C2XS ( http://search.cpan.org/~sisyphus/InlineX-C2XS-0.13/
    ) can help you to remove the Inline::C dependency from your module.
    It uses Inline::C to create the XS file (from your Inline C code) -
    and can also write you a stub .pm and Makefile.PL.
    </plug>

    I personally think that Inline::C is the best thing since sliced bread
    (and it astounds me that Ingy wants it to remain in its current,
    unmaintained, state), but I don't like to see modules using it -
    mainly because that adds an unnecessary dependency.

    That's why I wrote (and use) InlineX::C2XS ... but it could probably
    use some "outside assessment" - especially wrt the documentation.
    So ... if (but *only* if) you're interested, give it a try and see if
    it makes life simpler.

    Cheers,
    Rob
     
    sisyphus, Aug 26, 2008
    #4
  5. Thomas

    Guest

    Ben Morrow <> wrote:
    > Quoth Thomas <>:
    > > The following code works for me at the beginning of my own module which
    > > uses Inline C 0.44:
    > >
    > > use Inline (C => 'DATA',
    > > LIBS => 'foo.lib',
    > > BUILD_NOISY => 1,
    > > FORCE_BUILD => 1,
    > > );
    > >
    > > However, this variant:
    > >
    > > my $lib_path = 'foo.lib';
    > > use Inline (C => 'DATA',
    > > LIBS => $lib_path,
    > > BUILD_NOISY => 1,
    > > FORCE_BUILD => 1,
    > > );
    > >
    > > does not. It runs, but the string 'foo.lib' is not given as a library
    > > to Inline's make process so that I end up with an error "unresolved
    > > externals" when linking the DLL Inline creates as glue code. So a
    > > literal string is fine in that particular context, a variable is not.
    > > This is probably a basic language understanding problem of mine and has
    > > less to do with the Inline module, but I can't figure this one out
    > > alone.

    >
    > 'use' statements are executed at compile time, but assignments are not
    > executed until runtime. This means that when the 'use Inline' line is
    > executed, $lib_path doesn't yet have a value.


    Why is this? Since Perl does compile time constant folding, why not do
    compile time constant assignment as well? Is there a good reason not
    to, or it just the way the cookie crumbles?

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    The costs of publication of this article were defrayed in part by the
    payment of page charges. This article must therefore be hereby marked
    advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
    this fact.
     
    , Aug 26, 2008
    #5
  6. Thomas

    Ben Morrow Guest

    Quoth :
    > Ben Morrow <> wrote:

    [
    my $lib_path = "foo";
    use Inline ..., $lib_path, ...;
    ]
    > >
    > > 'use' statements are executed at compile time, but assignments are not
    > > executed until runtime. This means that when the 'use Inline' line is
    > > executed, $lib_path doesn't yet have a value.

    >
    > Why is this? Since Perl does compile time constant folding, why not do
    > compile time constant assignment as well? Is there a good reason not
    > to, or it just the way the cookie crumbles?


    I don't know. One sort-of good reason is that the variable must be
    reassigned-to every time the block is entered (in the general case)
    anyway, so it would be awkward to make the first assignment happen
    early.

    I would really like a Perl6ish

    my $x :BEGIN = "foo";

    construct. I wonder how hard that would be? Data::Alias must already
    have most of what you need (tracing the boundaries of a particular
    assignment and executing it specially)...

    Ben

    --
    "Faith has you at a disadvantage, Buffy."
    "'Cause I'm not crazy, or 'cause I don't kill people?"
    "Both, actually."
    []
     
    Ben Morrow, Aug 26, 2008
    #6
  7. writes:

    > Ben Morrow <> wrote:
    >> Quoth Thomas <>:
    >> > The following code works for me at the beginning of my own module which
    >> > uses Inline C 0.44:
    >> >
    >> > use Inline (C => 'DATA',
    >> > LIBS => 'foo.lib',
    >> > BUILD_NOISY => 1,
    >> > FORCE_BUILD => 1,
    >> > );
    >> >
    >> > However, this variant:
    >> >
    >> > my $lib_path = 'foo.lib';
    >> > use Inline (C => 'DATA',
    >> > LIBS => $lib_path,
    >> > BUILD_NOISY => 1,
    >> > FORCE_BUILD => 1,
    >> > );
    >> >
    >> > does not. It runs, but the string 'foo.lib' is not given as a library
    >> > to Inline's make process so that I end up with an error "unresolved
    >> > externals" when linking the DLL Inline creates as glue code. So a
    >> > literal string is fine in that particular context, a variable is not.
    >> > This is probably a basic language understanding problem of mine and has
    >> > less to do with the Inline module, but I can't figure this one out
    >> > alone.

    >>
    >> 'use' statements are executed at compile time, but assignments are not
    >> executed until runtime. This means that when the 'use Inline' line is
    >> executed, $lib_path doesn't yet have a value.

    >
    > Why is this? Since Perl does compile time constant folding, why not do
    > compile time constant assignment as well? Is there a good reason not
    > to, or it just the way the cookie crumbles?


    Perl only does constant folding for actual constants. Which are never
    variables. You can in fact make use of this at compile time:

    #!/usr/bin/perl -w
    use strict;
    use constant PATH => "foo.lib" ;

    use Inline (C => 'DATA',
    LIBS => PATH,
    BUILD_NOISY => 1,
    FORCE_BUILD => 1,
    );


    --
    Joost Diepenmaat | blog: http://joost.zeekat.nl/ | work: http://zeekat.nl/
     
    Joost Diepenmaat, Aug 26, 2008
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Abhi
    Replies:
    2
    Views:
    750
    E. Robert Tisdale
    Jul 3, 2003
  2. Alvin
    Replies:
    7
    Views:
    487
    E. Robert Tisdale
    May 6, 2005
  3. Replies:
    3
    Views:
    471
  4. Daniel Vallstrom
    Replies:
    2
    Views:
    1,942
    Kevin Bracey
    Nov 21, 2003
  5. TGOS
    Replies:
    3
    Views:
    384
    Kevin Bracey
    Feb 28, 2005
Loading...

Share This Page