Why Is 'Return a or B' a Void Value Expression Error in Ruby

Why is `return a or b` a void value expression error in Ruby?

return a or b is interpreted as (return a) or b, and so the value of return a is necessary to calculate the value of (return a) or b, but since return never leaves a value in place (because it escapes from that position), it is not designed to return a valid value in the original position. And hence the whole expression is left with (some_void_value) or b, and is stuck. That is what it means.

How do I fix the error void value expression?

You need an elsif to let ruby know where the conditions change. Here is the correct code:

if str == "xxx"
puts "X Wins!"
return true
elsif str == "ooo"
puts "O Wins!"
return true
end

You also need to end your if blocks.

why loop do throws void value error?

i++ may be perfectly valid. For example,

1++ 3
#=> 4
1++

3
#=> 4

That's because both of these expressions are parsed to

1 + +3

and then to

1 + 3
#=> 4

Your expression is therefore equivalent to

loop do 
i + (break if i > 5)
end

A void value exception was raised because break if i > 5 does not return a value.

You want

i = 0
loop do
i += 1
break if i > 5
end
i #=> 6

or (my preference)

i = 0
loop do
i += 1
raise StopIteration if i > 5
end
i #=> 6

Kernel#loop handles the StopIteration exception by breaking out of the loop.

Ruby alternative to void return type

Put

return nil

in the last statement in method.

Or simply

nil

Log4Net Could not find schema information messages

I had a different take, and needed the following syntax:

[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.xml", Watch = true)]

which differs from xsl's last post, but made a difference for me. Check out this blog post, it helped me out.

Turn a hash symbol to string and apply .ord method (for an offset)

If I understand your question correctly, I think this gives you want you want:

class Hash
def transpose_key(offset)
map do |key, value|
t = (key.to_s.ord - "a".ord + offset) % 26
[(t + "a".ord).chr.to_sym, value]
end.to_h
end
end

wrong_keys = { :a => "rope", :b => "knife", :x => "life-jacket", :z => "raft" }

puts wrong_keys.transpose_key(2)
# {:c=>"rope", :d=>"knife", :z=>"life-jacket", :b=>"raft"}

Array#to_h (v2.0+) is an alternative to the class method Hash::[] (v1.0+)for converting an array of two-element arrays to a hash:

a = [[1,2],[3,4]]
Hash[a] #=> {1=>2, 3=>4}
a.to_h #=> {1=>2, 3=>4}

If we removed .to_h from the method we would find that the value returned by map (to which to_h is applied) is:

[[:c, "rope"], [:d, "knife"], [:z, "life-jacket"], [:b, "raft"]]

To use Hash#each_key, you could do this:

class Hash
def transpose_key(offset)
each_key.with_object({}) do |key,h|
t = (key.to_s.ord - "a".ord + offset) % 26
h[(t + "a".ord).chr.to_sym] = self[key]
end
end
end

puts wrong_keys.transpose_key(2)
# {:c=>"rope", :d=>"knife", :z=>"life-jacket", :b=>"raft"}

On reflection, I prefer the latter method.

How to write a switch statement in Ruby

Ruby uses the case expression instead.

case x
when 1..5
"It's between 1 and 5"
when 6
"It's 6"
when "foo", "bar"
"It's either foo or bar"
when String
"You passed a string"
else
"You gave me #{x} -- I have no idea what to do with that."
end

Ruby compares the object in the when clause with the object in the case clause using the === operator. For example, 1..5 === x, and not x === 1..5.

This allows for sophisticated when clauses as seen above. Ranges, classes and all sorts of things can be tested for rather than just equality.

Unlike switch statements in many other languages, Ruby’s case does not have fall-through, so there is no need to end each when with a break. You can also specify multiple matches in a single when clause like when "foo", "bar".

Two versions of fibonacci, null expression

It is because n == (0..1) is never satisfied if n is a number. The range 0..1 is not a number. A minimum fix is:

(0..1) === n

Is Ruby pass by reference or by value?

In traditional terminology, Ruby is strictly pass-by-value. But that's not really what you're asking here.

Ruby doesn't have any concept of a pure, non-reference value, so you certainly can't pass one to a method. Variables are always references to objects. In order to get an object that won't change out from under you, you need to dup or clone the object you're passed, thus giving an object that nobody else has a reference to. (Even this isn't bulletproof, though — both of the standard cloning methods do a shallow copy, so the instance variables of the clone still point to the same objects that the originals did. If the objects referenced by the ivars mutate, that will still show up in the copy, since it's referencing the same objects.)



Related Topics



Leave a reply



Submit