Ruby help / if (cond or cond)


#1

Why this code doesn’t work as expected? It raises exceptions everytime.
Tried with || operator, too.

validates_each :x, :y do |record, attr|
record.errors.add (attr, ‘between 1 and 100’) if (attr.to_i>100 or
attr.to_i<0)
end


They say money can’t buy happiness? Look at the smile on my face… ear
to ear, baby!


#2

On 3/31/06, Constantin G. removed_email_address@domain.invalid wrote:

Why this code doesn’t work as expected? It raises exceptions everytime.
Tried with || operator, too.

validates_each :x, :y do |record, attr|
record.errors.add (attr, ‘between 1 and 100’) if (attr.to_i>100 or
attr.to_i<0)
end

What exception are you getting?

Also, you have a logical error in there. “Between 1 and 100” isn’t
the same thing as “Not greater than 100 and not less than 0.”


#3

Cam pe la 03/31/2006 07:12 PM, James L. scrise:

What exception are you getting?

Also, you have a logical error in there. “Between 1 and 100” isn’t
the same thing as “Not greater than 100 and not less than 0.”

Sorry for the confusion, I don’t get an exception. “The logical error”
is the problem. The expression “attr.to_i>100 or attr.to_i<0” seems to
evaluate true no matter what. “Not between 1 and 100” is not the same
thing as “Greater than 100 or less than 0”?


They say money can’t buy happiness? Look at the smile on my face… ear
to ear, baby!


#4

“Not between 1 and 100” is not the same

thing as “Greater than 100 or less than 0”?

0 is not between 1 and 100 but it is not (> 100 or < 0)

“Constantin G.” removed_email_address@domain.invalid
wrote in message news:removed_email_address@domain.invalid…


#5

On 3/31/06, Constantin G. removed_email_address@domain.invalid wrote:

thing as “Greater than 100 or less than 0”?
When you say “no matter what” are you sure that you aren’t just
passing in 0 and expecitng it to fail validation?

If you really want “Between 1 and 100” (inclusive, I assume) then you
want to check for “attr.to_i > 100 || attr.to_i < 1”

–James


#6

Constantin G. wrote:

I understand now the logical flaw. Still doesn’t work: attr.to_i
evaluates to some strange number (14009), and if I use attr.to_s or just
attr, it echoes out the letters “x” or “y”.

It looks like you’re getting the Symbol objects that represent the
different attributes rather than the actual attribute values. It appears
that the example usage in the documentation is out of date. The example
has

class Person < ActiveRecord::Base
validates_each :first_name, :last_name do |record, attr|
record.errors.add attr, ‘starts with z.’ if attr[0] == ?z
end
end

Which is the idiom you’re following. But if you look at the source, the
yield statement is actually

yield record, attr, value

So your code should be

validates_each :x, :y do |record, attr, value|
record.errors.add (attr, ‘between 1 and 100’) if (value.to_i>100 ||
value.to_i<0)
end

Also, if those attributes represent numeric values naturally, there’s no
need to call to_i on them. Here’s probably the cleanest solution is

validates_each :x, :y do |record, attr, value|
record.errors.add(attr, ‘between 1 and 100’) if
(1…100).include?(value)
end


#7

Cam pe la 03/31/2006 10:31 PM, Jon B. scrise:

[…] It appears
that the example usage in the documentation is out of date. […]

Thanks for the solution. I didn’t expected the example to be out of
date.

Also, if those attributes represent numeric values naturally, there’s no
need to call to_i on them. Here’s probably the cleanest solution is

validates_each :x, :y do |record, attr, value|
record.errors.add(attr, ‘between 1 and 100’) if
(1…100).include?(value)
end

I’m not used to ruby paradigm, and more used to C. The construct
(1…100) isn’t just using a lot of memory only for a test? What if I
wanted to check if it’s between 1 and 1_000_000_000?


They say money can’t buy happiness? Look at the smile on my face… ear
to ear, baby!


#8

Cam pe la 03/31/2006 08:28 PM, James L. scrise:

validates_each :x, :y do |record, attr|

want to check for “attr.to_i > 100 || attr.to_i < 1”

I understand now the logical flaw. Still doesn’t work: attr.to_i
evaluates to some strange number (14009), and if I use attr.to_s or just
attr, it echoes out the letters “x” or “y”.


They say money can’t buy happiness? Look at the smile on my face… ear
to ear, baby!


#9

Constantin G. wrote:

I’m not used to ruby paradigm, and more used to C. The construct
(1…100) isn’t just using a lot of memory only for a test? What if I
wanted to check if it’s between 1 and 1_000_000_000?

A Range object doesn’t actually contain any real values, it just has a
begin and end value. Range.include? does just 2 tests (the same ones you
were doing). This is very different from Array.include? which actually
tests each object. You certainly wouldn’t want to do this:

(1…100).to_a.include?(value)

While rails is straightforward enough that you can do lots in it without
really understanding ruby, you’ll be able to do much more and much more
easily if you get a good understanding of the underlying language. I’d
recommend reading the pickaxe book (2nd edition).


#10

On Mar 31, 2006, at 2:31 PM, Jon B. wrote:

validates_each :x, :y do |record, attr, value|
record.errors.add(attr, ‘between 1 and 100’) if
(1…100).include?(value)
end

but you probably meant:
unless (1…100).include?(value)
^^^^^^

:wink:

Rob B. http://agileconsultingllc.com
removed_email_address@domain.invalid
+1 513-295-4739


#11

Cam pe la 03/31/2006 11:21 PM, Jon B. scrise:

While rails is straightforward enough that you can do lots in it without
really understanding ruby, you’ll be able to do much more and much more
easily if you get a good understanding of the underlying language. I’d
recommend reading the pickaxe book (2nd edition).

I’m reading the free edition (1st ed.). With time, Ruby patterns will be
accepted in my way on thinking.


They say money can’t buy happiness? Look at the smile on my face… ear
to ear, baby!