| [reply] [d/l] |
Normally, one would not expect to be able to compare four numbers with a fifth number by bitwise or-ing the four numbers together and comparing the result to the fifth number. In the general case, this would not work. It took me three readings of the code to understand why the author *expected* it to work.
If 256 weren't a power of two, there wouldn't even be a presumption that it might work. It's a lowlevel bit-fiddling dirty-trick (attempted) solution to a higher-level problem, by no means a natural way to go about the thing at hand. Notice I did not say it isn't *the* natural way; I said it is not *a* natural way at all. Id est, it doesn't make sense.
This is why it's arguable :-) Things like this depend so much on experience with the domain and various programming styles. For me the authors intent was immediately obvious and the style a completely natural one. I can imagine writing the same code myself. I fiddle with IP addresses a great deal in various languages, and you're doing bit-mask type operations on them all of the time. I think about IP addresses and net masks in terms of bits and bytes. So, to me, boolean logic makes complete sense in this particular domain.
The problem for me is that you get bitten by Perl's DWIMary. In Perl you're trained think that Perl will do the "right thing" when given things that look like numbers. In this particular instance Perl doesn't. I think it's a good thing that the Perl 6 folk are giving us separate operators to prevent future confusion.
I can completely see your point of view, and it's nothing I'd start a religious war over, but I do think it's arguable.
| [reply] |
So, to me, boolean logic makes complete sense in this particular domain.
Boolean logic is a natural way to solve the problem.
A recursive or iterative solution would also be
natural. The OP however instead attempted to
combine the individual bits of the four parts of the
address (only, they didn't combine quite the way he
expected). I'd wager that the person who wrote
this code has spent significant time working with
a relatively low-level third-generation language such
as C. (Especially, since it came off a non-Perl
mailing list originally, but you can tell also from
the style of the code.)
The problem for me is that you get bitten by Perl's DWIMary. In Perl you're trained think that Perl will do the "right thing" when given things that look like numbers.
Yeah, but in Perl you're not trained to write code like
that. The code in question looks distinctly like it
was written by a C programmer. (C programmers play
weird tricks with bitwise operations all the time.)
There are much more Perlish ways to solve the problem,
not least of which is to use Regex::Common.
I stand by my statement that in some respects I agree
with the poster who said the code doesn't make sense;
particularly, it may not make immediate sense to a
Perl programmer with little background in C (and
languages like C).
I can completely see your point of
view, and it's nothing I'd start a religious war
over, but I do think it's arguable.
It does depend on your perspective. I suppose the
guy who wrote the code thought it made sense. (Of
course, he also thought it would work...) But I
don't think it's surprising that to flyingmoose,
a Perl programmer, it didn't make sense. And, in
a way, he's right. After three readings I understood
why the author thought the code would work, but on
the other hand, fundamentally he's using a bitwise
operation to accomplish a logical operation. That
is, he's doing bitwise-or of four numbers together in
order to figure out whether all of them (logical and)
meet a certain condition. Assuming for the moment
that we apply tye's two-stroke fix that makes the
code work as intended, it still only works because of
certain bit-related properties of the numbers in
question (centering around the fact that 256 is a
power of 2). You can see why someone might view
this as unintuitive.
As far as an IP address being under the hood a single
four-byte number, if the code used pack/unpack or
something to convert the four numbers into a single
four-byte number, or a hex representation, and then
operated on that, I would consider that a (not the,
but a) natural solution. In fact, for certain more
complex IP-address calculations, especially having
to do with network masks, that might even be _the_
natural solution. But the code in question doesn't
treat the IP address as a four-byte number; it
doesn't really do anything even _similar_ to treating
it as a four-byte number. If anything, it tries to
treat it as N sets of four bits, and checks to see
whether N is more than 8. That's a completely
different approach from treating it as a single
32-bit number.
So, in conclusion, flyingmoose is not smoking crack
(or, at least, if he is, you can't tell that from
the node in question).
;$;=sub{$/};@;=map{my($a,$b)=($_,$;);$;=sub{$a.$b->()}}
split//,".rekcah lreP rehtona tsuJ";$\=$;[-1]->();print
| [reply] |
Assuming for the moment that we apply tye's two-stroke fix that makes the code work as intended, it still only works because of certain bit-related properties of the numbers in question (centering around the fact that 256 is a power of 2).
In this particular domain each number should be a single byte. The bit related property isn't arbitrary or coincidental - it's the very essence of the thing we're testing for. To me it's an obvious property that or-ing them together should result in a number less than 256. To others it may not be.
You can see why someone might view this as unintuitive.
Of course. It's a completely reasonably attitude. Just not a universal one.
To others, myself included, using a bitwise numerical or is a completely intuitive solution. Whether somebody find it obvious or not is going to be dependent on their experience.
I too would use Regexp::Common, but only because I loathe reinventing wheels. Are the regexpes that Regexp::Common::net uses internally any more or less "intuitive" that the other solutions offered? This, of course, depends on how familiar you are with Perl's regular expressions. It also depends on the domain you're playing with.
I still think the real problem is with the behaviour of the | operator in Perl. This is one of the very few places where the difference between a string containing a number and a number makes a real difference.
With all the other numerical operations numbers and strings containing numbers are treated the same way. It's only the bitwise operators that are treated differently. This, in my opinion, was a poor design choice and doesn't fit in with the way the rest of Perl is organised (eq vs ==, . vs +, etc.) I imagine this is one of the reasons the numerical and string bitwise operators are being separated out in Perl 6.
For example, the difference between the bitwise string and numerical operators has caught me out when I was manipulating preference values that were being represented as bit masks. Comparing different preferences sometimes worked and sometimes didn't, depending on whether preferences got injected into the system as strings or numbers. Since the injection of values happened a long way from the comparisons it took a heck of a long time to figure out what was going on.
(For those about to chime in and say bitmasks were a poor choice for preference values - I quite agree. We were manipulating values from a third party application.)
So, in conclusion, flyingmoose is not smoking crack (or, at least, if he is, you can't tell that from the node in question).
I never accused anybody of smoking crack.
Ignoring the reinventing the wheel issue, and just comparing the bitwise and comparison solutions, on some days I might even agree that the comparison solution was a better design choice.
However I do disagree that the original solution "does something that doesn't even make sense". It makes perfect sense - it's just that Perl in this particular instance does something that most developers wouldn't expect.
| [reply] [d/l] [select] |