I'm going to assume you really misunderstand and aren't trolling,
because even if you are trolling, maybe this explanation will come in
useful for someone else.
Chris said:
if select([@sock], [], [], 0.1)
@sock.recv()
etc, etc.
Your program is asking the "recv" block to be called if select()
returns true.
Actually no. In Ruby, as I showed in my previous message, "if _____"
doesn't test to see if "_____" is true or false, it check to see if it
is true, false, nil, or another object.
If _____ is false, then the conditional is not executed. If _____ is
nil, then the conditional is executed. Otherwise, whether _____ is the
boolean 'true' or whether it is any other non-nil, non-false object, the
conditional is executed.
Conditional execution truth table:
parameter | conditional executed
------------------------------------
false | no
true | yes
nil | no
anything else | yes
And note, that 'anything else' includes some things that may surprise
people used to programming in C, including the number 0, an empty
string, an empty array, etc.
What I'm asking Ruby to do, is to execute that bit of code if the result
of calling select() is not nil.
We have established the following:
(a) select() returns nil or anArray (from a RTFM).
(b) nil != true (axiom).
Right
(c) anArray != true. (See your irb snippet above).
Right, however
anArray = []
if anArray
puts "This is printed because anArray is non-nil and not false"
else
puts "This is not printed."
end
Thus you are requesting the block never to be called. Your program is
working perfectly, and the socket is brimming with bytes
I'm confused by your talking about the block. There is a block in that
bit of code, but it isn't inside the conditional.
In this section of code:
if select([@sock], [], [], 0.1)
retval += @sock.recv(256)
if stop_pattern
if retval =~ stop_pattern
break
end
end
end
This bit:
retval += @sock.recv(256)
if stop_pattern
if retval =~ stop_pattern
break
end
end
Will get executed if "select([@sock], [], [], 0.1)" returns something
which isn't nil, and isn't the boolean 'false'. The documentation of
'select' says that it returns nil, or an array. If it returns an array,
that
Try this (and pardon my ruby, I've forgotten most of the syntax):
while true
sockArr = select([@sock], [], [], 0.1)
if !sockArr.nil? and sockArr.at(0).include?(@sock)
@sock.recv(256)
etc, etc.
That code will work, but, as I explained above, it isn't really
necessary. Since the only possible non-nil return value of
"select([@sock], [], [], 0.1)" is a set of arrays including "@sock". I
don't really need to look at the return value. I know that if select()
returns non-nil, my socket will not block if I try to read it.
I hope that convinces you. If not, try playing around with if, and
select() and see if you can figure out what I'm talking about.
I think this does point out a need in Ruby for a 'to_bool' operator.
Obviously, this kind of test already happens behind the scenes when it
comes to conditionals.
All you'd need is the equivalent of:
class Object
def to_bool
true
end
end
class NilClass
def to_bool
false
end
end
class TrueClass
def to_bool
true
end
end
class FalseClass
def to_bool
false
end
end
If nothing else, this would help explain to people why "if 0" takes the
'true' branch. Just point out that 0.to_bool is true
Any opinions? Should I make an RCR?
Ben