elsunless: Compiles but does not run. Standard?

F

Fred Talpiot

In Ruby:
1) 'if' can be followed by 'elsif'.
2) 'unless' can NOT be followed by 'elsif'. It gets a syntax error.
3) 'unless' can be followed by 'elsunless', but it does not run okay.
3a) 'if' can also be followed by 'elsunless', with the same dismal
results.
4) So what's the standard?
5) The following code:
-------------------
puts 'ruby version: ' + RUBY_VERSION + ', ' + RUBY_RELEASE_DATE + ' for
' + RUBY_PLATFORM

unless true
puts "wrong wrong"
elsunless false
puts 'weird, but logical'
elsunless true
puts 'truly strange'
else
puts 'weirder yet' # This is what pops out!
end

# and 'elsif' is a syntax error following 'unless'
-------------------
Produces the following on WinXP:
ruby unless.rb
ruby version: 1.8.6, 2007-09-24 for i386-mswin32
weirder yet

And, on Linux:

$ ruby unless.rb
ruby version: 1.8.6, 2007-09-24 for x86_64-linux
weirder yet

We can be sure this behavior is not as intended. We cannot be sure
exactly what was intended.

The following rule is from the wiki reference page:
http://en.wikibooks.org/wiki/Ruby_Programming/Syntax/Control_Structures#unless

|The unless expression is treated exactly like a negated if
expression:
|
| if !expression # is equal to using
| unless expression

Obviously, that rule is not being followed. If it were, the 'elsif'
would
be permitted.

The interpreter has a bug. The documentation may also be wrong, hard to
know for sure...

name already taken
 
P

Peter Hickman

Are you sure about this. I am getting:

fred.rb:4:in `x': undefined method `elsunless' for main:Object
(NoMethodError)

I think that there is no such thing as elsunless. How about some more
realistic test code?
 
N

Nobuyoshi Nakada

Hi,

At Wed, 12 Mar 2008 23:19:49 +0900,
Fred Talpiot wrote in [ruby-talk:294281]:
3) 'unless' can be followed by 'elsunless', but it does not run okay.
3a) 'if' can also be followed by 'elsunless', with the same dismal
results.

No such keyword.
unless true
puts "wrong wrong"
elsunless false

This is assumed a method call, but not reached.
 
S

Stefan Lang

2008/3/12 said:
[...]
puts 'ruby version: ' + RUBY_VERSION + ', ' + RUBY_RELEASE_DATE + ' for
' + RUBY_PLATFORM

unless true
puts "wrong wrong"
elsunless false
puts 'weird, but logical'
elsunless true
puts 'truly strange'
else
puts 'weirder yet' # This is what pops out!
end

elsunless is not a keyword in Ruby. Let's reformat your
code a little bit:

unless true
puts "wrong wrong"
elsunless false
puts 'weird, but logical'
elsunless true
puts 'truly strange'
else
puts 'weirder yet' # This is what pops out!
end

Syntax wise, Ruby sees the "elsunless" occurences here
as plain method calls. Since the unless condition is true,
the whole block gets never executed and there's no exception.

Let's compare in irb:

irb(main):001:0> elsif true
SyntaxError: compile error
(irb):1: syntax error, unexpected kELSIF
elsif true
^
from (irb):1
irb(main):002:0> elsunless true
NoMethodError: undefined method `elsunless' for main:Object
from (irb):2

Stefan
 
T

Thomas Wieczorek

unless true
puts "wrong wrong"
elsunless false
puts 'weird, but logical'
elsunless true
puts 'truly strange'
else
puts 'weirder yet' # This is what pops out!
end

Ruby is an interpreted language, so it ignores your "unless true" part
and doesn't parse what's after it until the "else". Your code should
look like that:
unless true
puts "wrong wrong"
elsunless false
puts 'weird, but logical'
elsunless true
puts 'truly strange'
else
puts 'weirder yet' # This is what pops out!
end

Nobu is right. Try "unless false" instead of "unless true" and you'll
get a NameError
 
S

Stefan Lang

2008/3/12 said:
elsunless is not a keyword in Ruby. Let's reformat your
code a little bit:


unless true
puts "wrong wrong"
elsunless false
puts 'weird, but logical'
elsunless true
puts 'truly strange'
else
puts 'weirder yet' # This is what pops out!
end

Damn, the "else" should not be indented.

Stefan
 
F

Fred Talpiot

Yup, you guys were right about ONE thing, the 'elsunless' was
not being parsed. It ain't a keyword. It ain't nuthin'.


BUT the 'unless ... elsif' sequence SHOULD be accepted, if the
wiki is right. The wiki claims that 'unless X' is the same as
'if ! X'. And that is NOT true with regard to 'elsif'.

name already taken
 
P

Phlip

Each time you code 'unless else', Satan waterboards a kitten.

If matz had added 'elsunless' to the language, Satan would have moved
up to baby seals...
 
S

Stefan Lang

2008/3/12 said:
Yup, you guys were right about ONE thing, the 'elsunless' was
not being parsed. It ain't a keyword. It ain't nuthin'.


BUT the 'unless ... elsif' sequence SHOULD be accepted, if the
wiki is right. The wiki claims that 'unless X' is the same as
'if ! X'. And that is NOT true with regard to 'elsif'.

The wiki first describes the plain if expression - without
else or elsif. Then it describes unless and says it's the
opposite of if. And only afterwards comes the description
of else and elsif. Makes sense to me.

But it's a wiki and you're invited to improve it if you
think it needs clarification.

(Well, and I'd find it ugly if Ruby actually allowed and
elsif in an unless.)

Stefan
 
P

Phlip

Fred said:
BUT the 'unless ... elsif' sequence SHOULD be accepted, if the
wiki is right. The wiki claims that 'unless X' is the same as
'if ! X'. And that is NOT true with regard to 'elsif'.

I have a function, reflect{}, which uses RubyNode to turn Ruby's opcodes back
into legible source. Here they work with two if-style statements:

puts reflect{ if true then 42 elsif false then 41 else 40 end }
puts reflect{ unless x then 42 else 40 end }

They produced these:

if ( true ) then ( 42 ) else ( ( if ( false ) then ( 41 ) else ( 40 ) end ) )
end )
if ( x ) then ( 40 ) else ( 42 ) end

Because these statements came from raw opcodes (called "nodes" in the Ruby
source), reflect{} shows that elsif is syntactic sugar for else(if ...). There
is no unique elsif opcode.

And the compiler converted the unless into an 'if' with its 'then' and 'else'
blocks reversed. There is no 'unless' opcode. Simpler 'unless' expressions
become 'if !(...)'

This analysis does not explain why Matz did not provide elsunless. Maybe he
didn't want to get too close to the INTERCAL construct "come-from".

But this statement does not even compile (ruby -v 1.8.6):

reflect{ unless true then 42 elsif false then 41 else 40 end }

So if a Wiki lead you astray, go return the favor, and edit it.
 
L

Lionel Bouton

Fred said:
Yup, you guys were right about ONE thing, the 'elsunless' was
not being parsed. It ain't a keyword. It ain't nuthin'.


BUT the 'unless ... elsif' sequence SHOULD be accepted, if the
wiki is right.

Why should we care about this wiki? There are thousands of ressources on
Ruby. If you want to fix them when they aren't reliable enough, you are
welcomed to do so but I don't see what you expect us to do with
imaginary elsunless and elsif keywords in the unless constructs.

Lionel
 
F

Fred Talpiot

Lionel: I never meant you had to do anything, I was asking about the
standard.

Why the Wiki?
I went to http://www.ruby-lang.org/en/documentation/ and started looking
down the page for a 'language reference'. The wiki is the only one
described on that page as a 'reference' to the language. The rest of
the references there are to the libraries.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,763
Messages
2,569,562
Members
45,038
Latest member
OrderProperKetocapsules

Latest Threads

Top