Hi, I have a question about Ruby if constructs. Why aren’t they like
smalltalk if’s, where you have a boolean class and two subclasses: true
and false. They both have these methods: ifTrue and ifFalse. If you use
a block with a ifTrue on a True object, it will be yielded. If you use
it on a false object, nothing will happen.
So in ruby code:
true.if_true do #code will be executed
end
and:
false.if_true do #code will NOT be executed
end
and if_false is available too.
so you can do this too:
(var == ‘a’).if_true do
puts ‘var = “a”’
end
I know it would be difficult to do an if-else thing with this because
the return value from the block would be the receiver:
(var == ‘a’).if_true do
puts ‘var = “a”’
end.if_false do #code
end
So is this the reason for if(var == ‘a’) not being syntactic sugar for
(var == ‘a’).if_true?
Hi, I have a question about Ruby if constructs. Why aren’t they like
smalltalk if’s, where you have a boolean class and two subclasses: true
and false. They both have these methods: ifTrue and ifFalse. If you use
a block with a ifTrue on a True object, it will be yielded. If you use
it on a false object, nothing will happen.
They aren’t like Smalltalk ifs because Ruby isn’t Smalltalk. That
said, people have been able to make things that work remarkably
similar to the Smalltalk stuff. Do a search in the archives and you
should find it.
So is this the reason for if(var == ‘a’) not being syntactic sugar for
(var == ‘a’).if_true?
Thanks for answering!
Jules
What would be the point of creating another smalltalk like language?
smalltalk is still active as far as I can tell, so if you like
smalltalk, why not use that instead of ruby? I don’t want the ifs to be
like smalltalk if. I want standard ifs.
An interesting difference, though, is that the Smalltalk version
utilizes the language’s capability to accept multiple blocks in a method
call – ‘ifTrue: [ … ] ifFalse: [ … ]’. In the Ruby version given,
it needs to have a (may be) hack to return the value of the original
condition, from the ‘if’ block.
and:
false.if_true do #code will NOT be executed
end
Just do this:
– BEGIN –
class Object
def if_true(&block)
block.call if self
self
end
def if_false(&block)
block.call unless self
self
end
end
– END –
(var == ‘a’).if_true do
puts ‘var = “a”’
end.if_false do #code
end
The above modifications to Object will allow this to work as well.
(Although I feel it necessary to add: that particular syntax is just,
well, horrid. The only possible advantage is variable scoping, and
even then there’s probably a better way to express what you want.)
You can define these methods in TrueClass and FalseClass so you don’t
polute the Object class.
I had thought about doing it that way, but then you could only use
that syntax on actual instances of TrueClass and FalseClass – if
statements are quite often applied to arbitrary objects since, IIRC,
everything other than FalseClass and NilClass is the same as true for
that purpose.
I’m not sure if I’m understanding your question, but it’s actually
easier than it was in Smalltalk.
In Ruby, everything but nil and False evaluates to true. There’s no
ifTrue: because you don’t need one. You can say if anything then
anything, and postconditions are supported too.
For example (Pseudo-Smalltalk in parens)
if group.members then group.some_action end
(members isNil ifFalse: [some_action])
unless group.save then some_action end
(group save ifTrue: [someAction]
some_action if !group.empty? – postcondition
(group isEmpty ifFalse: [someAction])
I’m finding it clearer and more terse than Smalltalk, with no added
limitations
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.