The Symbol Class
26 Jun 2015 GSoC-2015 · SymEngineHi everyone! The midterm evaluations for GSoC-2015 have arrived. These will last for about a week, in which we will be evaluated on the basis of our performance.
Beginning of this week, I got my PR merged. I had 49 randomly ordered commits that I managed to squeeze into only 13! I can say I have got a very good hold of git rebase -i
by now.
This week was spent more towards developing the wrappers for Symbol
class, adding methods, writing tests and trying to find memory leaks. The obvious choice to detect memory leaks is Valgrind, but after using RSpec, I am looking for a more Rubyish way to detect memory leaks. I am still going through some guides on how to detect memory leaks, be it Valgrind or something else. Any suggestions will be really appreciated. You can review the work in my PR #480 Support for Symbols in Ruby wrappers.
One of the things I felt like worth writing in a blog post is as follows
Inheritance in Ruby C API
We know how inheritance works in C++, if we have a class, say SubC
, that is the subclass of a particular class, say C
. When we make an object of the class SubC
, the constructor for the class C
is called first and then the constructor for SubC
along with the initialization that it might need to do. In Ruby, this happens in two steps. One is a method call to .allocate
, which is most of the time done internally, and then the method .initialize
to initialize the content of the object. So, when I was writing the wrappers for Symbol
, Isuru, one of my team-mates, raised this question. Symbol
is a subclass of Basic
and I have the code in
void Init_symengine() {
m_symengine = rb_define_module("SymEngine");
//Basic class
c_basic = rb_define_class_under(m_symengine, "Basic", rb_cObject);
rb_define_alloc_func(c_basic, cbasic_alloc);
//Symbol class
c_symbol = rb_define_class_under(m_symengine, "Symbol", c_basic);
rb_define_alloc_func(c_symbol, csymbol_alloc);
Now overloading the allocate
method through the C API to set the custom allocate function has been deprecated and it is advised to use the rb_define_alloc_func
now. In the method, rb_define_class_under
, the third argument is the name of the base class. So the doubt was, will the function cbasic_alloc
be called along with csymbol_alloc
, since Basic
is the base class for Symbol
? And also csymbol_alloc
did nothing but called the cbasic_alloc
function inside it. So, will the function be called twice.
To get the answer, I tried searching on the internet and tried reading the source code, but couldn’t make much sense out of it. Neither anyone had made such classes and wrote about how they behave.
So, I got the function cbasic_alloc
to print ‘basic object allocated’ everytime it got called.
VALUE cbasic_alloc(VALUE klass){
VALUE obj;
basic_struct *struct_ptr;
obj = Data_Make_Struct(klass, basic_struct, NULL, cbasic_free, struct_ptr);
struct_ptr->data = NULL;
printf("basic object allocated\n");
return obj;
}
Now normally, expecting the same behaviour as C++ in C API, one would expect to see the message printed twice when a Symbol
object was created, but that’s not what I got.
//$ rspec spec --format documentation
SymEngine
SymEngine::Basic
.new
with no arguments
basic object allocated
returns a Basic object
SymEngine
SymEngine::Symbol
.new
with an integer as an argument
basic object allocated
returns a Symbol object
binary operations
Only csymbol_alloc
was called when Symbol
was instantiated. Maybe the sole responsibility to create an object is given to the function passed. The parameter passed as the base class might only be for identification in Ruby that what is a subclass of whom.
Soon, I will be adding support for Integer
and Rational
classes after which you will be able to form expressions using integers like (x+y)**2
instead of (x+y)*(x+y)
. You can follow the work in the PR #487 Support for Integer and Rational classes in Ruby wrappers
Next Week
The plan for next week is to completely support Integer
and Rational
classes along with automation of testing for memory leaks. I don’t even know, if it would be feasible to integrate testing of memory leaks to Continuous-Integration, but it’s a worth a shot. It will be very convenient to have an alert system that warns you about memory leaks everytime you push the code.
Commits
- Added source files for symbol
- Added expand method to Basic
- Added the to_s method that returns the string rep returns the string representation
- Added the tests for symbol from basic
- Moved the symbol related files to symengine/ruby
- Rearranged the tests betn Symbol and Basic, Corrected the descriptions
- Added the
==
operator for Basic class Added test for==
- Added method
!=
in Basic - Added
alloc_func
and removed repetitive headers
comments powered by Disqus