Hello all.
I’ve tried something like this:
‘a’.send(’==’, ‘b’) #it works, returns true
But
‘a’.send(’!=’, ‘b’)
said to me:
tricks.rb:11:in Kernel#send': undefined method
!=’ for “a”:String
(NoMethodError)
Where am I wrong?
V.
Hello all.
I’ve tried something like this:
‘a’.send(’==’, ‘b’) #it works, returns true
But
‘a’.send(’!=’, ‘b’)
said to me:
tricks.rb:11:in Kernel#send': undefined method
!=’ for “a”:String
(NoMethodError)
Where am I wrong?
V.
Victor S. wrote:
said to me:
tricks.rb:11:in
Kernel#send': undefined method
!=’ for “a”:String
(NoMethodError)Where am I wrong?
V.
a != b gets turned into !(a == b) or something like that.
So != isn’t really a method - it’s just syntax.
-Justin
From: Justin C. [mailto:[email protected]]
Sent: Friday, May 26, 2006 8:28 AM
a != b gets turned into !(a == b) or something like that.
So != isn’t really a method - it’s just syntax.
It’s intuitively understandable; but I feel myself very uncomfortable
when I
can call, but can’t send. OK, would remember this one.
-Justin
V.
I’ve tried something like this:
‘a’.send(’==’, ‘b’) #it works, returns true
Sorry. Return ‘false’, of couse.
V.
On 5/26/06, Victor S. [email protected] wrote:
From: Justin C. [mailto:[email protected]]
Sent: Friday, May 26, 2006 8:28 AM
…
It’s intuitively understandable; but I feel myself very uncomfortable when I
can call, but can’t send. OK, would remember this one.-Justin
You can’t call:
irb(main):007:0> ‘a’.!= ‘b’
SyntaxError: compile error
(irb):7: parse error, unexpected tNEQ
‘a’.!= ‘b’
^
So it actually makes sense: you can’t call, so you can’t send.
Quoting [email protected], on Fri, May 26, 2006 at 02:50:27PM +0900:
So, other question: is there way for uniform compare objects by some
operator? (where operator is either == or != or <, or even include?)
Perhaps <=>
Sam
From: Alder G. [mailto:[email protected]]
Sent: Friday, May 26, 2006 8:44 AM
You can’t call:
irb(main):007:0> ‘a’.!= ‘b’
SyntaxError: compile error
(irb):7: parse error, unexpected tNEQ
‘a’.!= ‘b’
^So it actually makes sense: you can’t call, so you can’t send.
Hmmm… Really
So, other question: is there way for uniform compare objects by some
operator? (where operator is either == or != or <, or even include?)
-Alder
Victor.
From: Sam R. [mailto:[email protected]]
Sent: Friday, May 26, 2006 9:11 AM
Quoting [email protected], on Fri, May 26, 2006 at 02:50:27PM +0900:
So, other question: is there way for uniform compare objects by some
operator? (where operator is either == or != or <, or even include?)Perhaps <=>
No-no.
The point was to do things like this:
def filter(object, op, criteria)
object.send op, criteria
end
filter ‘a’, :==, ‘b’
filter ‘Ruby’, :include?, ‘Ru’
filter 110, :<, 15
#filter ‘a’, :!=, ‘b’ <== doesn’t work!
Sam
V.
Quoting [email protected], on Fri, May 26, 2006 at 03:16:20PM +0900:
The point was to do things like this:
def filter(object, op, criteria)
object.send op, criteria
endfilter ‘a’, :==, ‘b’
filter ‘Ruby’, :include?, ‘Ru’
filter 110, :<, 15#filter ‘a’, :!=, ‘b’ <== doesn’t work!
Ok, I see.
Probably, its because you are showing us a small piece of a larger
puzzle, but
why not have filter take a block:
def filter(object, op, criteria)
yield object, criteria
end
filter(‘a’, ‘b’) { |o,c| o != c }
or even a proc:
def filter(object, op, criteria)
op.call(object, criteria)
end
filter(‘a’, Proc.new{ |o,c| o != c }, ‘b’)
Cheers,
Sam
From: Sam R. [mailto:[email protected]]
Sent: Friday, May 26, 2006 9:30 AM
No-no.
end
filter(‘a’, ‘b’) { |o,c| o != c }or even a proc:
def filter(object, op, criteria)
op.call(object, criteria)
end
filter(‘a’, Proc.new{ |o,c| o != c }, ‘b’)
OK, some more pieces of puzzle
Request.filter [
[:base_type, :==, ‘cpu’],
[:fullname, :include?, ‘Intel’],
[:frequency, :>, 2300]
]
For (a), filter as lambda is good; but for (b), I need some format I can
convert into plain SQL.
Strange things, right?
Sam
V.
Victor S. wrote:
filter 110, :<, 15
[:frequency, :>, 2300]
]
- I’m planning inside Request to do the following:
a) search some pre-fetched array (through Array#select)
b) so some additional request to databaseFor (a), filter as lambda is good; but for (b), I need some format I can
convert into plain SQL.
From ZenSpider’s Ruby QuickRef, with a couple of corrections:
Operators by Precedence:
:: .
[]
**
-(unary) +(unary) ! ~
<< >>
&
| ^
= < <=
<=> == === != =~ !~
&&
||
… …
=(+=, -=…)
not
and or
All of the above are just methods except these:
=, …, …, !, not, &&, and, ||, or, !=, !~, ::
In addition, assignment operators(+= etc.) are not user-definable.
You may want to transform &&, || and != into a certain proc and a
certain other string for use in SQL.
Perhaps something like this:
op = Hash.new do |h, k|
{ :sql => k,
:proc => proc {|obj, *args| obj.send(k, *args) } }
end
op[“&&”] = {:sql => " AND “, :proc => proc {|l,r| l && r } }
op[”||“] = {:sql => " OR “, :proc => proc {|l,r| l || r } }
op[”!=”] = {:sql => " <> “, :proc => proc {|l,r| l != r } }
op[”=="] = {:sql => " = ", :proc => proc {|l,r| l == r } }
op[“>”][:sql] #=> “>”
op[“>”][:proc].call(2, 1) #=> true
Cheers,
Dave
said to me:
tricks.rb:11:in
Kernel#send': undefined method
!=’ for “a”:String
(NoMethodError)
The syntax magic makes != work… but that doesn’t mean you can’t create
methods to do the same things. define_method is much more lenient on
method names than def is:
class Object
define_method(:<) {|arg| self < arg }
define_method(:>) {|arg| self > arg }
define_method(:!=) {|arg| self != arg }
end
1.send(:>, 5)
=> false
1.send(:<, 5)
=> true
From: Daniel S. [mailto:[email protected]]
Sent: Friday, May 26, 2006 10:18 AM
said to me:
define_method(:>) {|arg| self > arg }
define_method(:!=) {|arg| self != arg }
end1.send(:>, 5)
=> false1.send(:<, 5)
=> true
Wow! Elegant. Thanks.
V.
On 5/26/06, Daniel S. wrote:
1.send(:>, 5)
=> false1.send(:<, 5)
=> true
A good point.
:< and :>, though, are already methods!
1.methods.include? “>” #=> true
Cheers,
Dave
On 5/26/06, Daniel S. [email protected] wrote:
Trying to define a method != doesn’t wfm, even with define_method:
irb(main):013:0> class Object; define_method(:!=) {|arg| self != arg };
end
class Object; define_method(:!=) {|arg| self != arg }; end
SyntaxError: compile error
(irb):13: parse error, unexpected tNEQ, expecting tSTRING_CONTENT or
tSTRING_DBEG or tSTRING_DVAR or tSTRING_END
class Object; define_method(:!=) {|arg| self != arg }; end
^
On 5/26/06, Alder G. wrote:
Trying to define a method != doesn’t wfm, even with define_method:
irb(main):013:0> class Object; define_method(:!=) {|arg| self != arg }; end
class Object; define_method(:!=) {|arg| self != arg }; endSyntaxError: compile error
(irb):13: parse error, unexpected tNEQ, expecting tSTRING_CONTENT or
tSTRING_DBEG or tSTRING_DVAR or tSTRING_END
class Object; define_method(:!=) {|arg| self != arg }; end
^
No, just that symbol syntax. :!= is not a valid symbol. “!=” will work
just fine, though.
irb(main):001:0> class << self
irb(main):002:1> define_method("!=") {}
irb(main):003:1> end
=> #Proc:0x00000000@:3(irb)
Cheers,
Dave
On 5/26/06, Dave B. [email protected] wrote:
^
Dave
Yup, good tip. However, the relations between the operator syntax and
the method calls reveals itself to be more mysterious than I thought:
class Foo
define_method(‘!=’) { ‘Foo#!= was called’ }
define_method(‘==’) { ‘Foo#== was called’ }
end
irb(main):003:0> foo = Foo.new
#Foo:0x2c88e28
irb(main):004:0> foo != 1
false # looks like ‘foo != arg’ isn’t simply syntactic sugar for
!foo.==(arg)
irb(main):005:0> foo.==
“Foo#== was called”
irb(main):008:0> foo.send ‘!=’
“Foo#!= was called” # And send seems to be the only way to call !=
But as far as Victor is concerned, as long as #send is used, those
methods would work as expected.
2006/5/26, Victor S. [email protected]:
#filter ‘a’, :!=, ‘b’ <== doesn’t work!
filter(‘a’, ‘b’) { |o,c| o != c }
- really, the former is used as bunch of filters:
For (a), filter as lambda is good; but for (b), I need some format I can
convert into plain SQL.
This solution is not very nice, but the usage of != as symbol in
awkward anyway, the only way I got it to work is this:
irb(main):036:0> :‘!=’
=> :“!=”
module Enumerable
def filter(criteria)
select do |x|
criteria.all? do |member, op, value|
if op == “!=”
x.send(member) != value
else
x.send(member).send(op, value)
end
end
end
end
end
irb(main):024:0> St = Struct.new :name, :size
=> St
irb(main):025:0> a=[St.new(“foo”, 10), St.new(“bar”, -20)]
=> [#<struct St name=“foo”, size=10>, #<struct St name=“bar”, size=-20>]
irb(main):026:0> a.filter [ [:name , “!=” , “foo”], [:size , :< , 0] ]
=> [#<struct St name=“bar”, size=-20>]
irb(main):027:0> a.filter [ [:name , “!=” , “foo”], [:size , :> , 0] ]
=> []
Strange things, right?
No, IMHO that’s a perfectly valid requirement.
Kind regards
robert
Alder G. wrote:
tSTRING_DBEG or tSTRING_DVAR or tSTRING_END
irb(main):003:0> foo = Foo.new
#Foo:0x2c88e28irb(main):004:0> foo != 1
false # looks like ‘foo != arg’ isn’t simply syntactic sugar for
!foo.==(arg)
Actually, it still is:
foo.==(1) returns the string ‘Foo#== was called’ which is true. Then it
is negated: false.
Try changing it to:
class Foo
define_method(’!=’) { puts ‘Foo#!= was called’ }
define_method(’==’) { puts ‘Foo#== was called’ }
end
And you will see it call ‘==’.
-Justin
On 5/26/06, Justin C. [email protected] wrote:
irb(main):002:1> define_method(“!=”) {}
define_method(‘!=’) { ‘Foo#!= was called’ }end
And you will see it call ‘==’.
-Justin
Do’h! You are correct, of course.
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.
Sponsor our Newsletter | Privacy Policy | Terms of Service | Remote Ruby Jobs