How to create a Ruby interface to C array - ruby

I have an array (can be more than just one array) in C. I need to build an interface so that ruby can modify/read the array values. I am building ruby modules in C so they later are used in ruby.
C file:
#include <ruby.h>
VALUE ParentModule;
uint8 variable = 7;
uint8 array[2];
VALUE get_variable(VALUE self)
{
return INT2NUM(variable);
}
VALUE set_variable(VALUE self, VALUE x)
{
variable = NUM2UINT(x);
return Qnil;
}
void Init_extension(void)
{
ParentModule = rb_define_module("ParentModule");
rb_define_method(ParentModule, "variable", get_variable, 0);
rb_define_method(ParentModule, "variable=", set_variable, 1);
}
Ruby file:
class Thing
def initialize
extend ParentModule
end
end
c = Thing.new
c.variable #=> will return the value 7
c.variable= 10 #=> will write 10 to variable in the C section.
c.variable #=> returns 10
So all this works great, but now I need to be able to do the same with an array. What I tried:
C file:
VALUE get_array_0(VALUE self)
{
return INT2NUM(array[0]);
}
VALUE set_array_0(VALUE self, VALUE x)
{
array[0] = NUM2UINT(x);
return Qnil;
}
/* this line is inside Init_extension function */
rb_define_method(ParentModule, "array[0]", get_array_0, 0);
What I am trying to do is name the set/get method to give an impression in ruby that I am "using" an array when is just really an interface to interact with the array that exists in C.
The C file compiles fine but when I try to call the method from Ruby, it complains saying that "array" is not a method
Ruby:
c = Thing.new
c.array[0] #=> NoMethodError (undefined method `array' for #<Thing:0x00000234523>)
What would be the best way to achieve this? (It must work for 2D arrays as well)
NOTE: Please edit my question if you find any information redundant.

What you want is not exactly possible. There is only one way that Ruby interprets this statement:
c.array[0]
That's equivalent to
c.array().[](0)
In other words, two method calls: array with no arguments called on c and then [] with one argument called on the return value of array. If that's the syntax you want, then you'll need to define your classes in a way such that these methods exist: ParentModule will need an array method that returns something responding to []. Since you don't want this to be an actual Array, you'll need to define another object with the [] method (this object can call back to ParentModule to do whatever you want).

You can use [] and []= as the method names to make your object appear array-like in Ruby:
rb_define_method(ParentModule, "[]", get_array, 1);
rb_define_method(ParentModule, "[]=", set_array, 2);
[] takes a single argument, the index of the item you want to look at, and []= takes two arguments, the index and the new value.
You can then implement them something like this:
VALUE get_array(VALUE self, VALUE idx)
{
return INT2NUM(array[NUM2INT(idx)]);
}
VALUE set_array(VALUE self, VALUE idx, VALUE x)
{
array[NUM2INT(idx)] = NUM2UINT(x);
return Qnil;
}
(Obviously this is just a simple example to show the idea, in reality you would want to check the index so it isn’t out of bounds, and also check the values so they make sense for the array type).
These methods will then be directly available on your object:
c = Thing.new
c[0] = 3
p c[0]

Related

Simple way to understand returning from a block in ruby

My code is supposed to print integers in an array.
odds_n_ends = [:weezard, 42, "Trady Blix", 3, true, 19, 12.345]
ints = odds_n_ends.select { |x| if x.is_a?(Integer) then return x end }
puts ints
It gives me an error in the 2nd line - in 'block in <main>': unexpected return (LocalJumpError)
When I remove the return, the code works exactly as desired.
To find the mistake in my understanding of blocks, I read related posts post1 and post2. But, I am not able to figure out how exactly are methods and blocks being called and why my approach is incorrect.
Is there some call stack diagram explanation for this ? Any simple explanation ?
I am confused because I have only programmed in Java before.
You generally don't need to worry exactly what blocks are to use them.
In this situation, return will return from the outside scope, e.g. if these lines were in a method, then from that method. It's the same as if you put a return statement inside a loop in Java.
Additional tips:
select is used to create a copied array where only the elements satisfying the condition inside the block are selected:
only_ints = odds_n_ends.select { |x| x.is_a?(Integer) }
You're using it as a loop to "pass back" variables that are integers, in which case you'd do:
only_ints = []
odds_n_ends.each { |x| if x.is_a?(Integer) then only_ints << x end }
If you try to wrap your code in a method then it won't give you an error:
def some_method
odds_n_ends = [:weezard, 42, "Trady Blix", 3, true, 19, 12.345]
ints = odds_n_ends.select { |x| if x.is_a?(Integer) then return true end }
puts ints
end
puts some_method
This code output is true. But wait, where's puts ints??? Ruby didn't reach that. When you put return inside a Proc, then you're returning in the scope of the entire method. In your example, you didn't have any method in which you put your code, so after it encountered 'return', it didn't know where to 'jump to', where to continue to.
Array#select basically works this way: For each element of the array (represented with |x| in your code), it evaluates the block you've just put in and if the block evaluates to true, then that element will be included in the new array. Try removing 'return' from the second line and your code will work:
ints = odds_n_ends.select { |x| if x.is_a?(Integer) then true end }
However, this isn't the most Ruby-ish way, you don't have to tell Ruby to explicitly return true. Blocks (the code between the {} ) are just like methods, with the last expression being the return value of the method. So this will work just as well:
ints = odds_n_ends.select { |x| if x.is_a?(Integer) } # imagine the code between {} is
#a method, just without name like 'def is_a_integer?' with the value of the last expression
#being returned.
Btw, there's a more elegant way to solve your problem:
odds_n_ends = [:weezard, 42, "Trady Blix", 3, true, 19, 12.345]
ints = odds_n_ends.grep(Integer)
puts ints
See this link. It basically states:
Returns an array of every element in enum for which Pattern ===
element.
To understand Pattern === element, simply imagine that Pattern is a set (let's say a set of Integers). Element might or might not be an element of that set (an integer). How to find out? Use ===. If you type in Ruby:
puts Integer === 34
it will evalute to true. If you put:
puts Integer === 'hey'
it will evalute to false.
Hope this helped!
In ruby a method always returns it's last statement, so in generall you do not need to return unless you want to return prematurely.
In your case you do not need to return anything, as select will create a new array with just the elements that return true for the given block. As ruby automatically returns it's last statement using
{ |x| x.is_a?(Integer) }
would be sufficient. (Additionally you would want to return true and not x if you think about "return what select expects", but as ruby treats not nil as true it also works...)
Another thing that is important is to understand a key difference of procs (& blocks) and lambdas which is causing your problem:
Using return in a Proc will return the method the proc is used in.
Using return in a Lambdas will return it's value like a method.
Think of procs as code pieces you inject in a method and of lambdas as anonymous methods.
Good and easy to comprehend read: Understanding Ruby Blocks, Procs and Lambdas
When passing blocks to methods you should simply put the value you want to be returned as the last statement, which can also be in an if-else clause and ruby will use the last actually reached statement.

How is Array#each implemented in Ruby?

I'm curious about the mechanism of collection and block in Ruby. We can define a class like this:
class Foo
include Enumerable
def initialize
#data = []
end
def each
if block_given?
#data.each { |e| yield(e) }
else
Enumerator.new(self, :each)
end
end
end
I want to know how #data.each can use the block { |e| yield(e) } as the parameter. I searched the implementation of Array#each:
rb_ary_each(VALUE array)
{
long i;
volatile VALUE ary = array;
RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
for (i=0; i<RARRAY_LEN(ary); i++) {
rb_yield(RARRAY_AREF(ary, i));
}
return ary;
}
but this doesn't even seem like a Ruby language implementation. How is Array#each implemented in Ruby?
Edit:
It looks like C code traverses the first to final array element and call ruby yield function with the parameter of the traversed array element. But where is the block passed to rb_ary_each function?
Here's a simple Ruby implementation of an each-like method that doesn't rely on the existence of any of Ruby's built-in iterator methods:
class List
def initialize(arr)
#arr = arr
end
def each
i = 0
while i < #arr.length
yield #arr[i]
i += 1
end
end
end
Usage:
l = List.new(['a', 'b', 'c'])
l.each {|x| puts x}
Output:
a
b
c
I may come late to this topic, but I guess that VALUE array is a object/struct instead of an primitive value as int, char, etc. So, what rb_ary_each method is receiving is a pointer/reference to the object/struct of the type VALUE. If that is true (I'm just guessing here for what I know about C) then the block is passed inside the object/struct with the remain arguments.
I'm also guessing that another object/struct should exist to hold the block/proc/lambda, so the VALUE object/struct should hold a pointer/reference to the first one.
If I'm wrong, please, someone correct me! Your question are much more related to how C works than Ruby.

Ruby: Retrieving values from method parameters

I'm trying to figure out how I can create a method in Ruby where I can retrieve values from the method's parameters such as strings/integers.
For example, if this were a function coded in C, it might be done similar to this:
main()
{
int value;
GetAnIntegerValue(value);
printf("The value is %d", value);
}
// The "value" integer variable is passed to it, and updated accordingly because of the use of the ampersand prior to the parameter
GetAnIntegerValue(&int value)
{
value = 5;
}
// The output would be "The value is 5"
I think the term for this is pass by value but I'm not sure. My mind is a little vague on this area and I couldn't find many decent results.
Here's my example Ruby function, the array that the parameters are being assigned to is only local to the class which is the reason for this usage:
def getRandomWordAndHint(&RandomWord, &RandomHint)
randIndex = rand(7)
RandomWord = EnglishLevel1Word[randIndex]
RandomHint = EnglishLevel1Hint[randIndex]
end
Cheers!i
Ruby is pass-by-value. Always. No exceptions. You cannot do pass-by-reference in Ruby.
What you can do, is put the object you want to change into some sort of mutable container:
class MutableCell
attr_accessor :val
def initialize(val)
self.val = val
end
end
def change_the_value(cell)
cell.val = 5
end
value = MutableCell.new(42)
change_the_value(value)
value.val
# => 5
Of course, you can just use an Array instead of writing your own MutableCell class, this is just for demonstration.
However, mutable state is a bad idea in general, and mutating arguments passed to methods is a really bad idea especially. Methods know about their own object (i.e. self) and thus can safely modify it, but for other objects, that's generally a no-go.

Some simple Ruby questions - iterators, blocks, and symbols

My background is in PHP and C#, but I'd really like to learn RoR. To that end, I've started reading the official documentation. I have some questions about some code examples.
The first is with iterators:
class Array
def inject(n)
each { |value| n = yield(n, value) }
n
end
def sum
inject(0) { |n, value| n + value }
end
def product
inject(1) { |n, value| n * value }
end
end
I understand that yield means "execute the associated block here." What's throwing me is the |value| n = part of the each. The other blocks make more sense to me as they seem to mimic C# style lambdas:
public int sum(int n, int value)
{
return Inject((n, value) => n + value);
}
But the first example is confusing to me.
The other is with symbols. When would I want to use them? And why can't I do something like:
class Example
attr_reader #member
# more code
end
In the inject or reduce method, n represents an accumulated value; this means the result of every iteration is accumulated in the n variable. This could be, as is in your example, the sum or product of the elements in the array.
yield returns the result of the block, which is stored in n and used in the next iterations. This is what makes the result "cumulative."
a = [ 1, 2, 3 ]
a.sum # inject(0) { |n, v| n + v }
# n == 0; n = 0 + 1
# n == 1; n = 1 + 2
# n == 3; n = 3 + 3
=> 6
Also, to compute the sum you could also have written a.reduce :+. This works for any binary operation. If your method is named symbol, writing a.reduce :symbol is the same as writing a.reduce { |n, v| n.symbol v }.
attr and company are actually methods. Under the hood, they dynamically define the methods for you. It uses the symbol you passed to work out the names of the instance variable and the methods. :member results in the #member instance variable and the member and member = methods.
The reason you can't write attr_reader #member is because #member isn't an object in itself, nor can it be converted to a symbol; it actually tells ruby to fetch the value of the instance variable #member of the self object, which, at class scope, is the class itself.
To illustrate:
class Example
#member = :member
attr_accessor #member
end
e = Example.new
e.member = :value
e.member
=> :value
Remember that accessing unset instance variables yields nil, and since the attr method family accepts only symbols, you get: TypeError: nil is not a symbol.
Regarding Symbol usage, you can sort of use them like strings. They make excellent hash keys because equal symbols always refer to the same object, unlike strings.
:a.object_id == :a.object_id
=> true
'a'.object_id == 'a'.object_id
=> false
They're also commonly used to refer to method names, and can actually be converted to Procs, which can be passed to methods. This is what allows us to write things like array.map &:to_s.
Check out this article for more interpretations of the symbol.
For the definition of inject, you're basically setting up chained blocks. Specifically, the variable n in {|value| n = yield(n, value)} is essentially an accumulator for the block passed to inject. So, for example, for the definition of product, inject(1) {|value| n * value}, let's assume you have an array my_array = [1, 2, 3, 4]. When you call my_array.product, you start by calling inject with n = 1. each yields to the block defined in inject, which in turns yields to the block passed to inject itself with n (1) and the first value in the array (1 as well, in this case). This block, {|n, value| n * value} returns 1 == 1 * 1, which is set it inject's n variable. Next, 2 is yielded from each, and the block defined in inject block yields as yield(1, 2), which returns 2 and assigns it to n. Next 3 is yielded from each, the block yields the values (2, 3) and returns 6, which is stored in n for the next value, and so forth. Essentially, tracking the overall value agnostic of the calculation being performed in the specialised routines (sum and product) allows for generalization. Without that, you'd have to declare e.g.
def sum
n = 0
each {|val| n += val}
end
def product
n = 1
each {|val| n *= val}
end
which is annoyingly repetitive.
For your second question, attr_reader and its family are themselves methods that are defining the appropriate accessor routines using define_method internally, in a process called metaprogramming; they are not language statements, but just plain old methods. These functions expect to passed a symbol (or, perhaps, a string) that gives the name of the accessors you're creating. You could, in theory, use instance variables such as #member here, though it would be the value to which #member points that would be passed in and used in define_method. For an example of how these are implemented, this page shows some examples of attr_* methods.
def inject(accumulator)
each { |value| accumulator = yield(accumulator, value) }
accumulator
end
This is just yielding the current value of accumulator and the array item to inject's block and then storing the result back into accumulator again.
class Example
attr_reader #member
end
attr_reader is just a method whose argument is the name of the accessor you want to setup. So, in a contrived way you could do
class Example
#ivar_name = 'foo'
attr_reader #ivar_name
end
to create an getter method called foo
Your confusion with the first example may be due to your reading |value| n as a single expression, but it isn't.
This reformatted version might be clearer to you:
def inject(n)
each do |value|
n = yield(n, value)
end
return n
end
value is an element in the array, and it is yielded with n to whatever block is passed to inject, the result of which is set to n. If that's not clear, read up on the each method, which takes a block and yields each item in the array to it. Then it should be clearer how the accumulation works.
attr_reader is less weird when you consider that it is a method for generating accessor methods. It's not an accessor in itself. It doesn't need to deal with the #member variable's value, just its name. :member is just the interned version of the string 'member', which is the name of the variable.
You can think of symbols as lighter weight strings, with the additional bonus that every equal label is the same object - :foo.object_id == :foo.object_id, whereas 'foo'.object_id != 'foo'.object_id, because each 'foo' is a new object. You can try that for yourself in irb. Think of them as labels, or primitive strings. They're surprisingly useful and come up a lot, e.g. for metaprogramming or as keys in hashes. As pointed out elsewhere, calling object.send :foo is the same as calling object.foo
It's probably worth reading some early chapters from the 'pickaxe' book to learn some more ruby, it will help you understand and appreciate the extra stuff rails adds.
First you need to understand where to use symbols and where its not..
Symbol is especially used to represent something. Ex: :name, :age like that. Here we are not going to perform any operations using this.
String are used only for data processing. Ex: 'a = name'. Here I gonna use this variable 'a' further for other string operations in ruby.
Moreover, symbol is more memory efficient than strings and it is immutable. That's why ruby developer's prefers symbols than string.
You can even use inject method to calculate sum as (1..5).to_a.inject(:+)

ruby and references. Working with fixnums

I know a bit about ruby way to handle objects and references. The replace stuff, ect ...
I know it d'ont work on fixnum, cause the var is the fixnum. But i wish to change the value of a fixnum inside a function, and that the value changed in the ouside var.
How can i do this ?
I guess i can use a string like this "1" but that's quite dirty.
Ruby will always pass-by-reference (because everything is an object) but Fixnum lacks any methods that allow you to mutate the value. See "void foo(int &x) -> Ruby? Passing integers by reference?" for more details.
You can either return a value that you then assign to your variable, like so:
a = 5
def do_something(value)
return 1 #this could be more complicated and depend on the value passed in
end
a = do_something(a)
or you could wrap your value in an object such as a Hash and have it updated that way.
a = {:value => 5}
def do_something(dict)
dict[:value] = 1
end
do_something(a) #now a[:value] is 1 outside the function
Hope this helps.
You could pass an array with a single number, like [1], or a hash like {value: 1}. Less ugly than a string, as your number itself remains a number, but less overhead than a new class...
When I was building a game I had the same problem you have. There was a numeric score that represented how many zombies you've killed and I needed to manually keep it in sync between Player (that incremented the score), ScoreBar and ScoreScreen (that displayed the score). The solution I've found was creating a separate class for the score that will wrap the value and mutate it:
class Score
def initialize(value = 0)
#value = value
end
def increment
#value += 1
end
def to_i
#value
end
def to_s
#value.to_s
end
end

Resources