Porting PHP iterative function which uses "static" to Ruby - ruby

I'm looking for the best way to implement a method originally from a PHP class in Ruby. The method uses PHP's "static" keyword to create a counter which can remember it's value from the last time the function was called.
function fetchRule()
{
static $index = 0;
$ret = null;
if(isset($this->rules[$index]))
{
$ret = $this->rules[$index];
}
$index = $ret == null ? 0 : $index++;
return $ret;
}
As you can see rules is an array member of the object. Every time the function is called it gets the next rule and then returns null at the end. I need to port this to ruby. There are probably a dozen ways to do it but I'm hoping to keep it simple.

Here the method in pure Ruby.
def fetch_rule
#rule_index ||= 0 # An instance variable of the object which will be set only if #rule_index is nil
ret = #rules[#rule_index] # A local variable
# Increases the index or resets it to 0 if `ret` is nil.
#rule_index = (ret.nil? ? 0 : #rule_index++)
ret # Returns the value implicitly. WARNING! Returns nil if the method reaches the end of the Array!
end
I think you have a small bug in your code above because you reset $index on every call to 0.
You should also check out TryRuby. It's a cool tutorial to start with Ruby.

Related

Using Ruby to solve a quiz

So I found this quiz on a website that I was excited to solve with my newly acquired Ruby skills (CodeAcademy, not quite finished yet).
What I want to do is make an array with 100 entries, all set to "open". Then, I planned to create a method containing a for loop that iterates through every nth entry of the array and changes it to either "open" or "closed", based on what it was before. In the for loop, n should be increased from 1 to 100.
What I have so far is this:
change_state = Proc.new { |element| element == "open" ? element = "closed" : element = "open" }
def janitor(array,n)
for i in 1..n
array.each { |element| if array.index(element) % i == 0 then element.change_state end }
end
end
lockers = [*1..100]
lockers = lockers.map{ |element| element = "closed" }
result = janitor(lockers,100)
When trying to execute I receive an error saying:
undefined method `change_state' for "closed":String (NoMethodError)
Anybody an idea what is wrong here? I kinda think I'm calling the "change_state" proc incorrectly on the current array element.
If you know the quiz, no spoilers please!
As you have implemented change_state, it is not a method of any class, and definitely not one attached to any of the individual elements of the array, despite you using the same variable name element. So you cannot call it as element.change_state.
Instead, it is a variable pointing to a Proc object.
To call the code in a Proc object, you would use the call method, and syntax like proc_obj.call( params ) - in your case change_state.call( element )
If you just drop in that change, your error message will change to:
NameError: undefined local variable or method `change_state' for main:Object
That's because the change_state variable is not in scope inside the method, in order to be called. There are lots of ways to make it available. One option would be to pass it in as a parameter, so your definition for janitor becomes
def janitor(array,n,state_proc)
(use the variable name state_proc inside your routine instead of change_state - I am suggesting you change the name to avoid confusing yourself)
You could then call it like this:
result = janitor(lockers,100,change_state)
Although your example does not really need this structure, this is one way in which Ruby code can provide a generic "outer" function - working through the elements of an array, say - and have the user of that code provide a small internal custom part of it. A more common way to achieve the same result as your example is to use a Ruby block and the yield method, but Procs also have their uses, because you can treat them like data as well as code - so you can pass them around, put them into hashes or arrays to decide which one to call etc.
There may be other issues to address in your code, but this is the cause of the error message in the question.

Bindings in Ruby. What is a good way to think of them. What do they contain

I am confused about bindings.
def repl(input_stream, output_stream)
loop do
output_stream.print "> "
input = input_stream.gets()
result = binding.eval(input)
output_stream.puts(result)
end
end
repl($stdin, $stdout)
I am going to call repl with just $stdin and $stdout. I need a dumbed down version of what the line:
binding.eval(input) is doing.
Bindings are just where we currently are in the call stack right? They hold the current local variables? Anything else? What's a good way to think of them differently from the current scope?
Objects of class Binding encapsulate the execution context at some particular place in the code and retain this context for future use. The variables, methods, value of self, and possibly an iterator block that can be accessed in this context are all retained. Binding objects can be created using Kernel#binding, and are made available to the callback of Kernel#set_trace_func.
static VALUE
bind_local_variable_defined_p(VALUE bindval, VALUE sym)
{
ID lid = check_local_id(bindval, &sym);
const rb_binding_t *bind;
if (!lid) return Qfalse;
GetBindingPtr(bindval, bind);
return get_local_variable_ptr(bind->env, lid) ? Qtrue : Qfalse;
}
Here is a example of Public Instance Methods
def get_binding(param)
return binding
end
b = get_binding("hello")
b.eval("param") #=> "hello"

No overload for method 'Write' takes 0 arguments

Getting the following exception:
No overload for method 'Write' takes 0 arguments at
#{SessionValue = Session["PracticeId"].ToString();}
Not able to understand what I'm doing wrong
Your code should be like this:
#{string SessionValue = string.Empty;}
#if(Session["PracticeId"] != null)
{
SessionValue = Session["PracticeId"].ToString();
}
You don't need to be putting the SessionValue variable assignment in #{} because the if statement is already providing you with server code context.

How can I get a function's name by its pointer in Lua?

In Lua I've created a pretty printer for my tables/objects. However, when a function is displayed, it's shown as a pointer.
I've been reading up on Lua Introspection but when I introspect the function with debug.getinfo() it won't return the function's name. This seems to be due to a scoping issue but I'm not sure how to get around it.
What is the best way to get a function's name using its pointer? (I understand functions are first class citizens in Lua and that they can be created anonymously, that's fine)
when you create the functions, register them in a table, using them as keys.
local tableNames = {}
function registerFunction(f, name)
tableNames[f] = name
end
function getFunctionName(f)
return tableNames[f]
end
...
function foo()
..
end
registerFunction(foo, "foo")
...
getFunctionName(foo) -- will return "foo"
For some reason, it seems to work only with number parameters (that is, active functions on the stack).
The script
function a() return debug.getinfo(1,'n') end
function prettyinfo(info)
for k,v in pairs(info) do print(k,v) end
end
prettyinfo(a())
prints
name a
namewhat global
but if I change the last line to
prettyinfo(debug.getinfo(a, 'n'))
it gives me only an empty string:
namewhat

What's the gain I can have with blocks over regular methods?

I am a Java programmer, and I am learning Ruby...
But I don't get where those blocks of codes can give me gain... like what's the purpose of passing a block as an argument ? why not have 2 specialized methods instead that can be reused ?
Why have some code in a block that cannot be reused ?
I would love some code examples...
Thanks for the help !
Consider some of the things you would use anonymous classes for in Java. e.g. often they are used for pluggable behaviour such as event listeners or to parametrize a method that has a general layout.
Imagine we want to write a method that takes a list and returns a new list containing the items from the given list for which a specified condition is true. In Java we would write an interface:
interface Condition {
boolean f(Object o);
}
and then we could write:
public List select(List list, Condition c) {
List result = new ArrayList();
for (Object item : list) {
if (c.f(item)) {
result.add(item);
}
}
return result;
}
and then if we wanted to select the even numbers from a list we could write:
List even = select(mylist, new Condition() {
public boolean f(Object o) {
return ((Integer) o) % 2 == 0;
}
});
To write the equivalent in Ruby it could be:
def select(list)
new_list = []
# note: I'm avoid using 'each' so as to not illustrate blocks
# using a method that needs a block
for item in list
# yield calls the block with the given parameters
new_list << item if yield(item)
end
return new_list
end
and then we could select the even numbers with simply
even = select(list) { |i| i % 2 == 0 }
Of course, this functionality is already built into Ruby so in practice you would just do
even = list.select { |i| i % 2 == 0 }
As another example, consider code to open a file. You could do:
f = open(somefile)
# work with the file
f.close
but you then need to think about putting your close in an ensure block in case an exception occurs whilst working with the file. Instead, you can do
open(somefile) do |f|
# work with the file here
# ruby will close it for us when the block terminates
end
The idea behind blocks is that it is a highly localized code where it is useful to have the definition at the call site. You can use an existing function as a block argument. Just pass it as an additional argument, and prefix it with an &

Resources