How to escape from a recursive method in ruby - ruby

I created a recursive function that tries to parse the information from the parsed list. It's kind of hard to explain, but it's something like
In a parse function that parses either a wikipedia Movie page or an Actor page, starts by parsing a filmography list from a wikipedia actor page -> call the same function on the parsed list -> repeat
I set a global variable that counts the number of iterations, but when I try to break out from the function and move on to the next step by doing,
if $counter > 10
return nil
end
but it does not immediately ends since there are still functions to be called left (since it's recursive). I tried to use "abort" but this one just terminated the program instead of moving on to the next one.
Is there a way to immedately stop the recursive run and move on to the next step without aborting the program?

A bit hard to answer without more code. But i guess you looking for next or break to jump out of recursiveness.
next
Jumps to the next iteration of the most internal loop. Terminates execution of a block if called within a block (with yield or call returning nil).
for i in 0..5
if i < 2 then
next
end
puts "Value of local variable is #{i}"
end
Result:
Value of local variable is 2
Value of local variable is 3
Value of local variable is 4
Value of local variable is 5
break
Terminates the most internal loop. Terminates a method with an associated block if called within the block (with the method returning nil).
for i in 0..5
if i > 2 then
break
end
puts "Value of local variable is #{i}"
end
Result:
Value of local variable is 0
Value of local variable is 1
Value of local variable is 2

Related

I tried to shorten the code by removing assignments, but the result completely changed somehow., any explanation?

I tried this example code to see if it actually work
--This example is from Programming in Lua Second Edition
function values (t)
local i = 0
return function ()
i = i + 1
return t[i]
end
end
t = {10, 20, 30}
iter = values(t)
while true do
local element = iter()
-- calls the iterator
if element == nil then
break
end
print(element) --> 10, 20, 30
end
I decided to change it a bit, I thought the code will get the same result but I think I was wrong
--This example is from Programming in Lua Second Edition
function values (t)
local i = 0
return function ()
i = i + 1
return t[i]
end
end
t = {10, 20, 30}
while true do
local element = values(t)()
-- calls the iterator
if element == nil then
break
end
print(element) --> This will print 10 forever if I don't stop the IDE
end
Why is iter important that much?
When you do local element = values(t)(), you are actually creating an iterator function every single time your loop is running. Take a note of your values function, see that it has a local variable called i. Every single time you are running this function, a local variable is initialized and sent to your inner function which handles the iteration. The original example is perfectly fine, however if you want to practice local and global variables, you may change the local i to a global variable i, or a different name and move it outside your function so it will not get called every time you run your iterate function (You may keep it local still, so the scope will be limited to current file). However, that is totally not recommended, since your value may be re-used some time later by another function or file, also it will limit you to one full iteration per run (Unless you set the value back to zero before retrying to iterate.)
local i = 0 -- Notice that the variable is taken out of the function.
-- With your example, the problem was that this variable was set to 0 for every
-- time you called the function.
function values (t)
return function ()
i = i + 1
return t[i]
end
end
t = {10, 20, 30}
while true do
local element = values(t)()
-- calls the iterator
if element == nil then
break
end
print(element) --> This will print 10 forever if I don't stop the IDE
end
Also keep performance in your mind, as every time you are iterating with your example, a function is being created, called, and then destroyed by the garbage collection. This is why the original example created an iterator function only once, and then called it multiple times, whereas your example creates an iterator function every time it is looping.
If all you need to do is to iterate through elements of a table, then lua already has generic for loop (pairs), check here and here. Example in your case (which also shortens your code by a lot):
local t = {10, 20, 30}
-- We don't need key in this case, but if you do, replace _ with k or
-- any other variable name you want.
for _, element in pairs(t) do
print(element)
end

Get loop value when condition is true in robotframework

I am new to Robot Framework, I want to get loop value when the condition is true. Below I mention sample code.
FOR ${INDEX} IN RANGE 1 10
Run Keyword If ${INDEX}==5
END
You are missing the call to a keyword, and I assume you don't want to continue the loop after it, so for example:
FOR ${INDEX} IN RANGE 1 10
Run Keyword If ${INDEX}==5 Run Keywords No Operation Exit For Loop
END
Log For loop variable is ${INDEX}

"for var = 1, 2" in Lua

What does this kind of loop do in Lua?
for count = 1, 2 do
-- do stuff
end
The variable count isn't used in the body of the loop.
It executes the body of the loop twice.
There's no need to refer to count inside the loop unless you need to know its current value.
for count = 1,5 do
print("Hello")
end
prints
Hello
Hello
Hello
Hello
Hello
In this case count is "dummy variable" - "dummy" in that a variable is used fulfill a certain construct even though the variable is not used. (Another common name for such a usage is _, although count arguably adds a little more semantic intent.)
Such a dummy variable is used because LUA loops require a variable / assignment in the grammar construct. However, there is no requirement that the variable is used - hence a "dummy".
.. A numeric for [loop] has the following syntax:
for var=exp1,exp2,exp3 do
something
end
That loop will execute something for each value of var from exp1 to exp2, using exp3 as the step to increment var. This third expression [exp3] is optional; when absent, Lua assumes one [1] as the step value.

Ruby Recursion Counter Without Global Variable

I am trying to count the number of times the method recurses during the life of the program. The code below gets the desired result, but uses global variables. Is there a way around this or a better way?
$count = 0
def AdditivePersistence(num)
return 0 if num.to_s.length == 1
numarr = num.to_s.chars.map!(&:to_i)
i = numarr.inject(&:+)
$count+=1
if i.to_s.length!=1
AdditivePersistence(i)
end
$count
end
Since you want the total number of recursive calls during the lifetime of the program, a global variable in some form is the only way you can do it. You can either use an explicit global variable, as you have done, or a global variable in disguise, such as a singleton class, or a thread-local variable. I will not illustrate those here since they are inferior to plain global variables for this use case.
You could take in an array with the first variable in the array being num and then the second being the count. then you just will do return [num, count]
Another option would be to update your method definition to accept the counter as an argument.
Using this approach, your method can just increment whatever counter value it receives and then pass the incremented value along in the recursive call.
def AdditivePersistence(num, counter)
return 0 if num.to_s.length == 1
numarr = num.to_s.chars.map!(&:to_i)
i = numarr.inject(&:+)
counter +=1
if i.to_s.length!=1
AdditivePersistence(i, counter)
end
counter
end
# usage
AdditivePersistence(12, 0)

While loop not exiting after condition met (Ruby)

I'm not a skillful programmer by any means, but everyone's got to start somewhere.
I've been trying to make a (very) basic maze-type in ruby, but I'm having difficulty with the while loop not exiting.
Room layout is an upside down t:
5
2
103
4
Going north twice from the center should change #loc to 5, say "End", and exit the loop:
elsif #loc == 2
#loc = 5
puts "End"
But it returns to the beginning of the while loop, stranding the player.
EDIT: there's some confusion about the code, so I'm removing the block and pointing you to
http://pastebin.com/EFWVBAhn
The line
while #loc != 5
is accessing a variable which is not being changed. The changes are happening to cmd.loc, which is not the same variable. That line needs to be
while cmd.loc != 5
in order to access the variable.
Also you need to quote your strings (e.g. if command == west should be if command == "west"); otherwise you're telling Ruby to compare to a variable called west, which doesn't exist, rather than the string "west".

Resources