Ralesk has asked for the wisdom of the Perl Monks concerning the following question:
Esteemed Monks,
I was dumb and accidentally anded some flags instead of orring them at some point when I wrote the part of the software that employs Win32::Sound — I would have found out way earlier, had SND_ASYNC not been 1, and so silently working as intended...
Today I found the bug, replaced things with bitwise ors, and wondered why this could ever have worked before, and it seems that in weird situations (such as the flags being used in the argument list of Win32::Sound::Play), the constants behave completely non-DWIMly.
So here's some examples:
C:\>perl -E "use Win32::Sound; say Win32::Sound::SND_ASYNC; say Win32: +:Sound::SND_LOOP; say Win32::Sound::SND_NODEFAULT;" 1 8 2
This should mean that SND_ASYNC and (as I erroneously wrote) SND_NODEFAULT is 0, right? 1 & 2 is zero, we all know that. Those two orred together is 3.
... Win32::Sound::Play($filename, Win32::Sound::SND_ASYNC & Win32::Sound:: +SND_NODEFAULT); ...
Lo and behold, that thing there has SND_ASYNC set. No, it's not a precedence issue, it would be the same if the bit construct were surrounded by an extra set of parentheses.
C:\>perl -E "use Win32::Sound; say Win32::Sound::SND_ASYNC & Win32::So +und::SND_NODEFAULT;" 1 C:\>perl -E "use Win32::Sound; $x = (Win32::Sound::SND_ASYNC & Win32:: +Sound::SND_NODEFAULT); say $x" 1 C:\>perl -E "use Win32::Sound; say (1 & 2);" 0 C:\>perl -E "use Win32::Sound; say ('1' & '2');" 0 C:\>perl -E "use Win32::Sound; my $as = Win32::Sound::SND_ASYNC; my $n +d = Win32::Sound::SND_NODEFAULT; say $as & $nd;" 0 C:\>perl -E "use Win32::Sound; my @as = Win32::Sound::SND_ASYNC; my @n +d = Win32::Sound::SND_NODEFAULT; say @as; say @nd; say (@as & @nd);" 1 2 1
There it is — & requires scalar values to bitwise and, so takes the length of the two list context return values, which is 1 for each because each is a one element array. Or, if anything, forcing list context on these guys seems to at least replicate the error — no clue why they'd be in list context there in the original usage!
This doesn't, however, explain why it works out of the box with |, where the list context hack doesn't:
C:\>perl -E "use Win32::Sound; my @as = Win32::Sound::SND_ASYNC; my @n +d = Win32::Sound::SND_NODEFAULT; say @as | @nd;" 1 C:\>perl -E "use Win32::Sound; $x = (Win32::Sound::SND_ASYNC | Win32:: +Sound::SND_NODEFAULT); say $x" 3
The only question I have is just: why?
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Win32::Sound constants are weird (autoloaded, not actual constants)
by beech (Parson) on Dec 16, 2017 at 02:18 UTC |