Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?

Using a scalar as a constant?

by Anonymous Monk
on Oct 15, 2008 at 12:52 UTC ( [id://717208] : perlquestion . print w/replies, xml ) Need Help??

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

I'm creating an app using wxperl and would like to use scalars to define my styles which are constants. For instance if creating a TextCtrl the code would look something like this:
Wx::TextCtrl->new( $self, -1, "", [5, 10], [-1, -1], wxTE_MULTILINE );
I'm unable to use a scalar in place of wxTE_MULTILINE

I've tried the following:

use vars qw($constantstring); my $style = 'wxTE_MULTILINE'; *constantstring=\"$style"; Wx::TextCtrl->new( $self, -1, "", [5, 10], [-1, -1], $style );
Is this even possible? If so what am I doing wrong?


Replies are listed 'Best First'.
Re: Using a scalar as a constant?
by Corion (Patriarch) on Oct 15, 2008 at 12:54 UTC

    wxTE_MULTILINE actually is a function which has some value, and that value seems to be not the string "wxTE_MULTILINE". So you can do it like this:

    ... my $style = wxTE_MULTILINE(); Wx::TextCtrl->new( $self, -1, "", [5, 10], [-1, -1], $style );

    Update: Fixed a typo spotted by Fletch

      I should have given more details initially. The wxTE_MULTILINE value is being retrieved from an XML file so I'm running into the same issue. This is what my XML entry looks like if it helps
      <text_ctrl internal_name="text_ctrl_details" parent="-1" value="" x_coordinate="100" y_coordinate="53" x_size="400" y_size="110" style="wxTE_MULTILINE" />
      I'm then using XML::Twig to parse the XML so my actual code looks like this for creating the TextCtrl:
      Wx::TextCtrl->new( $parent_panel, -1, $entry->att('value'), [$entry->a +tt('x_coordinate'), $entry->att('y_coordinate')], [$entry->att('x_siz +e'), $entry->att('y_size')], $entry->att('style') );
      I've tried making it a function in the XML file and it still fails to show up. It does however work if I assign the constant to a scalar like you described.

      Any thoughts?

        Ah. If you have

        my $style = 'wxTE_MULTILINE';

        and want to get at the value returned by the constant/function wxTE_MULTILINE, then you have to use eval:

        print $style; $style = eval $style; die $@ if $@; print $style;
        why not use xrc?
Re: Using a scalar as a constant?
by JavaFan (Canon) on Oct 15, 2008 at 13:21 UTC
    Isn't wxTE_MULTILINE already a constant? That is, a sub returning a fixed value.
      Correct, It is a constant but I'm retrieving it via XML so I suspect something is wrong with the XML format...

        What you're retrieving is the string with the value 'wxTE_MULTILINE', which also happens to the same as the name of the constant wxTE_MULTILINE, whose value we don't know.

        In order to set a scalar to the right value to use in place of the constant, you need to map from the string through to the value of the constant. Something along the lines of:

        sub map_constant_name { my ($name) = @_ ; # Let's not eval anything other than a simple name ! if ($name !~ /^\w+$/) { $@ = "will not map '$name'" ; return undef ; } ; # OK -- eval to try to get constant value my $val = eval "$name()" ; return $@ ? undef : $val ; } ;
        will do the trick, but is still pretty dangerous -- allowing the contents of the XML to run any subroutine visible at this point.

        Safer would be to construct a hash mapping allowed names to their values:

        my %constant_map = map { ($_, map_constant_name($_)) } qw(....) ;