Ask a Question related to Ruby, Design and Development.
-
Kurt M. Dresner #1
chaining comparisons
When I learned python I was overjoyed that I could evaluate 1 < 2 < 3
and get "true". I just realized that you can't do that in Ruby. Is
there a reason why? Is it good? I know I can use "between", but
still...
-Kurt
Kurt M. Dresner Guest
-
Chaining live video stream
:beer; Hello : I have a problem of server side "Stream class" and rebublish live video stream. In brief, I assume the live video stream can... -
Chaining streams between 2 media server
Hi i'm trying to setup a stream chaining between 2 flash media servers. Basically I have an swf that streams my camera to FS Server 1. In FS... -
Is it possible to predetermine the order of HttpModule calls or implement filter chaining in ASP.Net
Hi people, I am wondering if it is possible to pretermine the order of the HttpModules being executed. If not, how can one implement interceptor... -
comparisons and depth
sorry to post two questions in one day, but i have run into a second problem. i have a looping movie clip which changes _y position randomly with... -
chaining of -> operator
With total disregard for any kind of safety measures Chris Laird <chris@SPAM.pocketGUARDfluff.net> leapt forth and uttered: PHP4 doesn't... -
Daniel Carrera #2
Re: chaining comparisons
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
I don't know if there's a good reason for it, but I think it'd be cool if
Ruby had it.
On Sat, Jul 19, 2003 at 02:58:51PM +0900, Kurt M. Dresner wrote:- --> When I learned python I was overjoyed that I could evaluate 1 < 2 < 3
> and get "true". I just realized that you can't do that in Ruby. Is
> there a reason why? Is it good? I know I can use "between", but
> still...
>
> -Kurt
>
Daniel Carrera | OpenPGP fingerprint:
Mathematics Dept. | 6643 8C8B 3522 66CB D16C D779 2FDD 7DAC 9AF7 7A88
UMD, College Park | [url]http://www.math.umd.edu/~dcarrera/pgp.html[/url]
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.2 (SunOS)
iD8DBQE/GN7LnxE8DWHf+OcRAthlAJ4zuAlY0EjdVHEwFLohg/G8OwOsXwCgq63a
blsFqUDYa9irZbjUPNyEdDI=
=bI3R
-----END PGP SIGNATURE-----
Daniel Carrera Guest
-
Phil Tomson #3
Re: chaining comparisons
In article <20030719060149.GA2247@math.umd.edu>,
Daniel Carrera <dcarrera@math.umd.edu> wrote:>-----BEGIN PGP SIGNED MESSAGE-----
>Hash: SHA1
>
>I don't know if there's a good reason for it, but I think it'd be cool if
>Ruby had it.
>
>On Sat, Jul 19, 2003 at 02:58:51PM +0900, Kurt M. Dresner wrote:>> When I learned python I was overjoyed that I could evaluate 1 < 2 < 3
>> and get "true". I just realized that you can't do that in Ruby. Is
>> there a reason why? Is it good? I know I can use "between", but
>> still...
>>
I can see how it would be cool, however:
1 < 2 #this gives a value of true
1 < 2 < 3 #this calls the '<(3)' method on true
It essentially looks like:
(true) < 3
Which is meaningless.
to do this you've got to somehow change the parser so that for the special cases of
<,>,<=,>= you instead call the method on the middle value in the chain of thee values.
Or you've got to somehow make '1 < 2' return 2 instead of/or in addition to true.
Seems problematic and could very likely break things.
2.between?(1,3)
May not look as pretty, but works fine without potential parser headaches.
Phil
Phil Tomson Guest
-
Gavin Sinclair #4
Re: chaining comparisons
On Saturday, July 19, 2003, 3:58:51 PM, Kurt wrote:
I agree it would be cool, but it's pretty clear why Ruby doens't> When I learned python I was overjoyed that I could evaluate 1 < 2 < 3
> and get "true". I just realized that you can't do that in Ruby. Is
> there a reason why? Is it good? I know I can use "between", but
> still...
support it:
2 < 3 == true
1 < true == error
therefore 1 < 2 < 3 == error
Ruby is a very expression-oriented language, and derives its strength
from conceptual purity. If an expression evaluated to X in some
circumstances and Y in others, a small part of Ruby would be lost.
Gavin
Gavin Sinclair Guest
-
Daniel Carrera #5
Re: chaining comparisons
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
On Sat, Jul 19, 2003 at 03:47:38PM +0900, Gavin Sinclair wrote:I realize that this is a dumb question, but what is an expression-oriented> I agree it would be cool, but it's pretty clear why Ruby doens't
> support it:
>
> 2 < 3 == true
> 1 < true == error
> therefore 1 < 2 < 3 == error
>
> Ruby is a very expression-oriented language, and derives its strength
> from conceptual purity. If an expression evaluated to X in some
> circumstances and Y in others, a small part of Ruby would be lost.
language?
Can you contrast Ruby with a language that is not expression-oriented?
- --
Daniel Carrera | OpenPGP fingerprint:
Mathematics Dept. | 6643 8C8B 3522 66CB D16C D779 2FDD 7DAC 9AF7 7A88
UMD, College Park | [url]http://www.math.umd.edu/~dcarrera/pgp.html[/url]
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.2 (SunOS)
iD8DBQE/GOp2nxE8DWHf+OcRAjzWAJ0c6ZKLbvxueD6lSX4T7dWBhS0eMQ CeJA54
IFr+5WRHMr+tDTeIz+YDNwo=
=Y+Y0
-----END PGP SIGNATURE-----
Daniel Carrera Guest
-
Mark Wilson #6
Re: chaining comparisons
On Saturday, July 19, 2003, at 01:58 AM, Kurt M. Dresner wrote:
While I was writing this message, Phil responded with some similar> When I learned python I was overjoyed that I could evaluate 1 < 2 < 3
> and get "true". I just realized that you can't do that in Ruby. Is
> there a reason why? Is it good? I know I can use "between", but
> still...
>
> -Kurt
thoughts, but I will post anyway, with apologies for the areas of
duplication.
A few of thoughts:
1. It seems that in python '1 < 2 < 3' is sugar for '1 is less than 2
and 2 is less than 3'.
2. How does python handle '1 < 2 < 3 < 4'? How does python handle '1 <
2 or 5 < 4'?
2. In Ruby 1 < 2 is a representation of the Fixnum object 1 calling the
'<' method with argument Fixnum object 2. The object returned is 'true'
(an object of the TrueClass). In the expression '1 < 2 < 3', the 'true'
object calls the '<' method with argument '3', an a no method error is
raised.
3. You can write the expression in Ruby as '1 < 2 and 2 < 3'.
4. You could also modify the '<' method to return the value of the
argument given if it evaluates to 'true' -- however, you would have to
parse the output so that the last comparison returns 'true' and not the
last argument. The following just modifies the return value of '<' and
does not handle the problem of the method chain now returning the last
argument:
class Fixnum
alias old_less_than <
def < (arg)
if self.old_less_than(arg)
return arg
end
end
end
1 < 2 < 3 => 3
5. You could also parse input so that '1 < 2 < 3' is translated to '1 <
2 and 2 < 3'. I haven't thought about how to do this from within Ruby.
6. I prefer the explicit '1 < 2 and 2 < 3'.
Regards,
Mark
Mark Wilson Guest
-
Simon Strandgaard #7
Re: chaining comparisons
On Sat, 19 Jul 2003 15:58:51 +0900, Kurt M. Dresner wrote:
> When I learned python I was overjoyed that I could evaluate 1 < 2 < 3
> and get "true". I just realized that you can't do that in Ruby. Is
> there a reason why? Is it good? I know I can use "between", but
> still...
You can do this:
if [1, 2, 3].ordered?
puts "ok"
end
It will require that you extend the Array class yourself, like this:
class Array> expand -t4 b.rb
def ordered?
return true if self.empty?
a = self.first
self[1..-1].each { |b|
return false if a > b
a = b
}
true
end
end
p [].ordered? #=> true
p [2].ordered? #=> true
p [-1, 2, 3, 5].ordered? #=> true
p [17, 13, 11].ordered? #=> false
p [1, -1, 1, 0].ordered? #=> falseThe output is:>
true> ruby b.rb
true
true
false
false>
--
Simon Strandgaard
Simon Strandgaard Guest
-
Martin DeMello #8
Re: chaining comparisons
Gavin Sinclair <gsinclair@soyabean.com.au> wrote:
One way to do it would be to have 'if' call to_boolean on its argument,> On Saturday, July 19, 2003, 3:58:51 PM, Kurt wrote:
>>>> When I learned python I was overjoyed that I could evaluate 1 < 2 < 3
>> and get "true". I just realized that you can't do that in Ruby. Is
>> there a reason why? Is it good? I know I can use "between", but
>> still...
> I agree it would be cool, but it's pretty clear why Ruby doens't
> support it:
>
> 2 < 3 == true
> 1 < true == error
> therefore 1 < 2 < 3 == error
>
> Ruby is a very expression-oriented language, and derives its strength
> from conceptual purity. If an expression evaluated to X in some
> circumstances and Y in others, a small part of Ruby would be lost.
and have < return an object that carried some state around.
martin
Martin DeMello Guest
-
Gavin Sinclair #9
Re: chaining comparisons
On Saturday, July 19, 2003, 4:51:42 PM, Daniel wrote:
> On Sat, Jul 19, 2003 at 03:47:38PM +0900, Gavin Sinclair wrote:>> I agree it would be cool, but it's pretty clear why Ruby doens't
>> support it:
>>
>> 2 < 3 == true
>> 1 < true == error
>> therefore 1 < 2 < 3 == error
>>
>> Ruby is a very expression-oriented language, and derives its strength
>> from conceptual purity. If an expression evaluated to X in some
>> circumstances and Y in others, a small part of Ruby would be lost.Don't worry, I've never seen/heard that assortment of words either.> I realize that this is a dumb question, but what is an expression-oriented
> language?
What I mean is that Ruby gives primacy to expressions (as opposed to
statements). For instance (not tested):
extractor =
case opt
when "-r" then ReceiptExtractor
when "-t" then TransactionExtractor
end.new(filename)
Every chunk of code has a "return value" that can be used to build
larger expressions.
Try the concepts in the above code in just about any language :)> Can you contrast Ruby with a language that is not expression-oriented?
Many/most languages enforce a difference between "statement" and
"expression". Pascal is an example.
Gavin
Gavin Sinclair Guest
-
Brian Candler #10
Re: chaining comparisons
On Sat, Jul 19, 2003 at 02:58:51PM +0900, Kurt M. Dresner wrote:
You can also use range objects for a clean alternative to a <= b <= c :> When I learned python I was overjoyed that I could evaluate 1 < 2 < 3
> and get "true". I just realized that you can't do that in Ruby. Is
> there a reason why? Is it good? I know I can use "between", but
> still...
x = 2 # or 1 or 3
if (1..3) === x
puts "It's in the range"
end
The strange 'backwards' ordering is to support case statements, which make
it look much clearer:
case x
when (1..3)
puts "It's in the lower range"
when (4..6)
puts "It's in the upper range"
else
puts "It's out of range"
end
In the above, 3.5 is also 'out of range'. But the three-dot form of range
supports a <= b < c
puts "nope" if (1...3) === 3.0 # false
puts "yep " if (1...3) === 2.99 # true
case x
when (1...4) # 1 to 3.999
when (4...7) # 4 to 6.999
when (7...10) # 7 to 9.999
end
Cheers,
Brian.
Brian Candler Guest
-
Simon Strandgaard #11
Re: chaining comparisons
On Sat, 19 Jul 2003 18:41:33 +0900, Brian Candler wrote:
Work smarter, Not harder.> On Sat, Jul 19, 2003 at 05:08:03PM +0900, Simon Strandgaard wrote:> self == sort>> You can do this:
>>
>> if [1, 2, 3].ordered?
>> puts "ok"
>> end
>>
>>
>> It will require that you extend the Array class yourself, like this:
>>>> class Array>> > expand -t4 b.rb
>> def ordered?
> end
> end
>
> (I'm a lazy typist :-)
I know sort, But this solution didn't come to mind.
Yes. Avoiding temporary copy were my goal when I started writing it.> Both versions generate a temporary copy of the array, e.g. self[1..-1] does
> that too. But you can avoid it:
As you can see I apparently forgot it in the hurry :-)
[snip enum#ordered?]Enum is Nice.> You can then check whether all the lines in a file are ordered, for example,
> without reading it into memory. (I am a big fan of Enumerable :-)
Some more thoughts on #ordered?
Supplying an operator, could be useful?
[3, 2, 1].ordered? :> #=> true
[2, 2, 2].ordered? :> #=> false
[2, 2, 2].ordered? :>= #=> true
Supplying an block could also be useful?
[2, 2, 2].ordered? { |a, b| (((a-b) ^ (b-a)) % 3) == 0 }
#=> true
[1, 2, 3].ordered? { |a, b| (((a-b) ^ (b-a)) % 3) == 0 }
#=> false
--
Simon Strandgaard
Simon Strandgaard Guest
-
Martin DeMello #12
Re: chaining comparisons
Simon Strandgaard <0bz63fz3m1qt3001@sneakemail.com> wrote:
This (anti?)pattern always bothers me - surely a 2-element sliding> class Array
> def ordered?
> return true if self.empty?
> a = self.first
> self[1..-1].each { |b|
> return false if a > b
> a = b
> }
> true
> end
> end
window is a common enough pattern that we should capture it once and for
all in Enumerable.
It's in Joel VanderWerf's excellent EnumerableTools, but people tend not
to include external packages when writing quick scripts. For instance,
the current script would simply be
class Array
def ordered?
each_cluster(2){|i,j| return false if i > j}
true
end
end
Personally, I'd like to see an each and an eachn, both taking block
arity into account:
a = *(1..6)
a.eachn {|x,y| p [x,y]} #=> [1,2] [3,4] [5,6]
a.each {|x,y| p [x,y]} #=> [1,2] [2,3] [3,4] [4,5] [5,6]
This would also preserve the semantics of 'each' only consuming one
element per iteration.
martin
Martin DeMello Guest
-
dblack@superlink.net #13
Re: chaining comparisons
Hi --
On Sat, 19 Jul 2003, Kurt M. Dresner wrote:
Matz's reason, in rejecting this in RCR form, was, "It's hard to> When I learned python I was overjoyed that I could evaluate 1 < 2 < 3
> and get "true". I just realized that you can't do that in Ruby. Is
> there a reason why? Is it good? I know I can use "between", but
> still...
define semantics of chain comparison in "OO" way. Use ranges instead."
(See <http://www.rubygarden.org/article.php?sid=286>.)
David
--
David Alan Black
home: [email]dblack@superlink.net[/email]
work: [email]blackdav@shu.edu[/email]
Web: [url]http://pirate.shu.edu/~blackdav[/url]
dblack@superlink.net Guest
-
Yukihiro Matsumoto #14
Re: chaining comparisons
Hi,
In message "Re: chaining comparisons"
on 03/07/19, news_chr <swap@gmx.net> writes:
|class Fixnum
| alias __lt <
| alias __le <=
| alias __gt >
| alias __ge >=
| def <(r)
| __lt(r) ? r : nil
| end
| def <(r)
| __lt(r) ? r : nil
| end
| def <=(r)
| __le(r) ? r : nil
| end
| def >(r)
| __gt(r) ? r : nil
| end
| def >=(r)
| __ge(r) ? r : nil
| end
|end
|
|
|class NilClass
| def <(r) self end
| def <=(r) self end
| def >(r) self end
| def >=(r) self end
|end
|
|
|p ((4 < 5) < 6) < 7 # 7
|
|p ((4 < 5) < 5) < 7 # nil
|
|p ((4 < 5) >= 5) < 7 # 7
|----
|
|Personally I wouldn't mind such a semantic but it is
|probably too wired for general consumption ...
They used to work like this long time ago. But I felt the semantic
was too weird.
matz.
Yukihiro Matsumoto Guest
-
Pit Capitain #15
Re: chaining comparisons
On 19 Jul 2003 at 17:41, Brian Candler wrote:
I'm not Dave Thomas :-) but you can also use inject here:> Both versions generate a temporary copy of the array, e.g. self[1..-1] does
> that too. But you can avoid it:
>
> module Enumerable
> def ordered?
> first = true
> prev = nil
> each do |item|
> if first
> first = false
> else
> return false if prev > item
> end
> prev = item
> end
> return true
> end
> end
module Enumerable
def ordered?
inject { | last, item | return false unless last < item; item }
true
end
end
Regards,
Pit
Pit Capitain Guest
-
Brian Candler #16
Re: chaining comparisons
On Sat, Jul 19, 2003 at 11:23:04PM +0900, Pit Capitain wrote:
Which implementation of 'inject' are you using? The one in PragProg requires> I'm not Dave Thomas :-) but you can also use inject here:
>
> module Enumerable
> def ordered?
> inject { | last, item | return false unless last < item; item }
> true
> end
> end
an initial value to be passed as a parameter.
With an array of N elements you either need to do N-1 comparisons, or you
need to start with a sentinel value which is guaranteed to be less than all
other elements (nil and 0 both aren't suitable). So I don't see how the
above works, but without its partner 'inject' implementation I can't comment
further.
Regards,
Brian.
Brian Candler Guest
-
Pit Capitain #17
Re: chaining comparisons
On 20 Jul 2003 at 0:10, Brian Candler wrote:
It's Andy's Windows installer version:> Which implementation of 'inject' are you using? The one in PragProg requires
> an initial value to be passed as a parameter.
D:\Temp>ruby -v
ruby 1.8.0 (2003-05-26) [i386-mswin32]
And ri says about inject:
D:\Temp>ri inject
This is a test 'ri'. Please report errors and omissions
on [url]http://www.rubygarden.org/ruby?RIOnePointEight[/url]
------------------------------------------------------
Enumerable#inject
enumObj.inject(initial) {| memo, obj | block } -> anObject
enumObj.inject {| memo, obj | block } -> anObject
---------------------------------------------------------------------
Combines the elements of enumObj by applying the block to an
accumulator value (memo) and each element in turn. At each step,
memo is set to the value returned by the block. The first form lets
you supply an initial value for memo. The second form uses the
first element of the collection as a the initial value (and skips
that element while iterating).
This is what the second form does.> With an array of N elements you either need to do N-1 comparisons,
This is what the first form would do.> or you
> need to start with a sentinel value which is guaranteed to be less than all
> other elements (nil and 0 both aren't suitable).
BTW, if you wanted to add the compare method as a parameter as
someone else suggested, you could define
module Enumerable
def ordered?( compare_method = :< )
inject { | last, item |
return false unless last.send( compare_method, item )
item
}
true
end
end
and then call it like
p [ 1, 2, 2 ].ordered? # => false
p [ 1, 2, 2 ].ordered?( :<= ) # => true
Isn't it fun to code in Ruby :< )
Regards,
Pit
Pit Capitain Guest
-
Josef 'Jupp' Schugt #18
Re: chaining comparisons
Saluton!
* Kurt M. Dresner; 2003-07-19, 11:33 UTC:a < b and b < c imply a < c. But what if you want to evaluate> When I learned python I was overjoyed that I could evaluate 1 < 2 <
> 3 and get "true". I just realized that you can't do that in Ruby.
> Is there a reason why?
a < b > c? Which conditons do you require to be met?
(1) a < b, b > c and a < c
(2) a < b, b > c and a > c
(3) a < b, b > c and nothing more
Some examples:
2 < 3 > 1 -> (2), (3)
1 < 3 > 2 -> (1), (3)
2 < 3 > 2 -> (3)
It seems to be better *not* to use '<' and the like. Better use
methods that can be applied to an arbitrary number of elements:
def increasing(*list)
return true if list.length < 2
y = nil
list.each {|x|
return false unless y.nil? or y < x
y = x
}
true
end
Gis,
Josef 'Jupp' Schugt
--
N'attribuez jamais à la malice ce que l'incompétence explique !
-- Napoléon
Josef 'Jupp' Schugt Guest
-
Jason Creighton #19
Re: chaining comparisons
On Sat, 19 Jul 2003 14:58:51 +0900
"Kurt M. Dresner" <kdresner@cs.utexas.edu> wrote:
[url]http://www.rubygarden.org/article.php?sid=286[/url]> When I learned python I was overjoyed that I could evaluate 1 < 2 < 3
> and get "true". I just realized that you can't do that in Ruby. Is
> there a reason why? Is it good? I know I can use "between", but
> still...
So basically, it's because it's hard to implement, even more so because
true/false/nil are singleton objects. (So you can't, for instance, save state
in a particular instance of 'true', because there's only one.)
Jason Creighton
Jason Creighton Guest
-
Jason Creighton #20
Re: chaining comparisons
On Sun, 20 Jul 2003 00:10:25 +0900
Brian Candler <B.Candler@pobox.com> wrote:
The inject in 1.8 defaults its initial value to the first item in the collection.> On Sat, Jul 19, 2003 at 11:23:04PM +0900, Pit Capitain wrote:>> > I'm not Dave Thomas :-) but you can also use inject here:
> >
> > module Enumerable
> > def ordered?
> > inject { | last, item | return false unless last < item; item }
> > true
> > end
> > end
> Which implementation of 'inject' are you using? The one in PragProg requires
> an initial value to be passed as a parameter.
Jason Creighton
Jason Creighton Guest



Reply With Quote

