Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

How to make bi-modal variables like $! ?

by bikeNomad (Priest)
on Jun 28, 2001 at 19:45 UTC ( [id://92331]=perlquestion: print w/replies, xml ) Need Help??

bikeNomad has asked for the wisdom of the Perl Monks concerning the following question:

As you know, the error variable $! has both a numeric and a string value, depending on which context it's used in (that is, the numeric value may be 2, while the string value is "No such file or directory"). I'd like to make error variables like this (assigning to $! doesn't work right). How can I do it? I tried the following, which didn't work:

#!/usr/bin/perl -w use strict; use Inline 'C'; my $v; set_both($v, "I'm a string too!", 123); print $v+0, " $v\n"; __END__ __C__ void set_both(SV* var, char* str, int i) { sv_setpv(var, str); sv_setiv(var, i); }

Replies are listed 'Best First'.
Re: How to make bi-modal variables like $! ?
by japhy (Canon) on Jun 28, 2001 at 20:14 UTC
    You'll need to do some overloading.
    package DualVar; use overload ( '""' => sub { $_[0][0] }, '0+' => sub { $_[0][1] }, fallback => 1, ); sub new { bless [ @_[1,2] ], $_[0] } 1;
    And that's all!
    use DualVar; my $x = DualVar->new("japhy", 19); printf "I'm %s, and I'm %d years old.\n", $x, $x;


    japhy -- Perl and Regex Hacker
(tye)Re: How to make bi-modal variables like $! ?
by tye (Sage) on Jun 28, 2001 at 20:33 UTC

    See SetDualVar, which includes XS code (C code) that sets the string/number value of a scalar without invalidating the other.

            - tye (but my friends call me "Tye")
      Cool! Re-writing the guts of SetDualVar using Inline, it looks like:

      #!/usr/bin/perl -w # Solution by Kenneth Albanowski <kjahds@kjahds.com> # from the module SetDualVar-1.0.tar.gz # re-written using Inline. use strict; use Inline 'C'; my $v; set_both($v, "I'm a string too!", 123); print $v+0, " $v\n"; __END__ __C__ void set_both(SV* variable, SV* string, SV* numeric) { SvPV(string, PL_na); if(!SvPOKp(string) || (!SvNOKp(numeric) && !SvIOKp(numeric)) ) { croak("Usage: set_both variable,string,numeric"); } sv_setsv(variable,string); if(SvNOKp(numeric)) { sv_setnv(variable,SvNV(numeric)); } else { sv_setiv(variable,SvIV(numeric)); } SvPOK_on(variable); }
Re: How to make bi-modal variables like $! ?
by cLive ;-) (Prior) on Jun 29, 2001 at 01:41 UTC
    Cheat - use @err and force context :)
    my @err = build_error("Something went wrong",5); print "The error message is: @err\n"; print "The error number is: ".@err."\n"; exit(0); sub build_error { my @err; $err[0] = $_[0]; int($_[1]); $err[$_[1]-1] = '' if ($_[1]-1 > 0); return @err; }
    cLive ;-)
Re: How to make bi-modal variables like $! ?(boo)
by boo_radley (Parson) on Jun 28, 2001 at 20:04 UTC
      How can I tell what context (string/numeric) it's being accessed in?
Re: How to make bi-modal variables like $! ?
by bart (Canon) on Apr 22, 2005 at 07:27 UTC
    Some things must have changed over the last few years... but now we have Scalar::Util, which includes the function dualvar:
    dualvar NUM, STRING
    Returns a scalar that has the value NUM in a numeric context and the value STRING in a string context.
    $foo = dualvar 10, "Hello"; $num = $foo + 2; # 12 $str = $foo . " world"; # Hello world
Re: How to make bi-modal variables like $! ?
by bwana147 (Pilgrim) on Jun 28, 2001 at 20:03 UTC

    I don't know if that's at all possible. AFAIK, $! is magic, in the sense of internal perl magic.

    You can try to work around with ^H. If your error messages are not meant for anything but displaying on a terminal, you can append a series of ^H after your digit to overwrite it, then the message, which won't change the numeric value. Not really helpfull in a log file, but it works on a term:

    $error = "2\x08message"; print $error+0 . "\n"; print "$error\n";

    HTH

    --bwana147

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others pondering the Monastery: (3)
As of 2024-03-19 07:50 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found