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

How to force syswrite to write numbers? A number is a numerical value; I do not mean the squiggly lines we draw to represent numbers.

Perl keeps changing the values I try to write, in accordance with its 'does what you expect it to do' philosophy. Three days of official and unofficial documentation, I can't find a solution.

Some examples of Perl changing types behind my back: with this line: syswrite($SERIALPORT, $packet_out)

$packet_out = 4; On the serial wire: 0x34 (which is ASCII code for character 4) $packet_out = '4'; On the serial wire: 0x34 (which is ASCII code for character 4) $packet_out = 0x65; On the serial wire: 0x31 0x30 0x31 (which, bizarrely, is ASCII code fo +r '101' which is a string of the decimal ASCII code for 'e' which has + the ASCII code 0x65)
When I say syswrite 4, I want a number 4 to go out the wire. This must be possible, and discussed already; anyone know how or where? I open the port like this:
unless (open ($SERIALPORT, "+<", $comport)) {die "Cannot open $comport +: $!"} system("stty -cstopb hupcl ignbrk -iexten -echo -echoe -echok " . "-echoctl -echoke -crtscts -ignpar cs8 9600 time 5 -icrnl " . "-ixon -opost -isig -icanon -F $comport"); die unless binmode($SERIALPORT, ':raw:bytes'); #numerous variations tr +ied

Replies are listed 'Best First'.
Re: syswrite numbers, not strings
by BrowserUk (Patriarch) on Dec 18, 2014 at 04:43 UTC
    When I say syswrite 4, I want a number 4 to go out the wire.

    Try this and see if it satisfies your requirement:

    syswrite( $SERIALPORT, pack 'C', 4 );

    Then go read perlfunc:pack().


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      Thanks. Like some of the approaches I've tried, it works for values that are not assigned to printable ASCII characters. If the value is assigned to a printable character in the ASCII set, then Perl will send the character from the ASCII set. So:
      syswrite( $SERIALPORT, pack 'C', 44 ); #writes 0x2C onto the wire, so Perl evidently sees ASCII character 0d4 +4 in this case, not number 0d44
      I have studied the pack, unpack, and packtut extensively, and conclude that they do not get the chance to come into play: Perl is tinkering with the write.
        0x2c and 0d44 are just different representations of the same number.
        I have studied the pack, unpack, and packtut extensively, and conclude that they do not get the chance to come into play: Perl is tinkering with the write.

        Sorry, but you are wrong. Your problem is one of your perception. Perl doesn't "tinker with the write".

        A byte with the numeric value of 44 is simply the bit pattern 00101100. It will only be interpreted as an ascii character by whatever you are using to look at it.


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.

        Since I have a logic analyzer available to me, I connected it to my PC's serial port, ran your code and captured a trace, which I put as the image on my profile node.

        (I thought the monks might be curious to see what a byte on a serial port "looks" like.)

Re: syswrite numbers, not strings
by Anonymous Monk on Dec 18, 2014 at 08:19 UTC
    I don't see anything bizarre about it.
    $ perl -E 'say 0x65' 101
    This is how integers get promoted to strings. Why is that unexpected? People would get confused if they typed perl -E 'say 2 + 2' and got 'end of transmission' byte.

    Perhaps you mean that syswrite should be special and different from say, print... I don't agree, consistency is a good thing

      Perhaps I just like variables to be firmly typed, so I can stand on them without wobbling. Bizarreness is defined by point of view, so we can certainly have different bizarres. I don't think I said anything to imply that a special case need exist. I like your print 0x65 example.

        While you could try using a module like Variable::Strongly::Typed, it probably would be of little help. As best I can tell, Variable::Strongly::Typed, only prevents you from assigning the wrong type of value to variables. It does not try to prevent implicit stringification of numbers nor numification of strings. Also, the documentation implies it uses a regex to determine if a value is a number.

        There is also typesafety, but the documentation says it's for objects, so it may also be of little help.

        Also, there is PerlGP, which claims to provide strong typing. Never heard of it before now, so I don't know just what it provides.