Reply to topic  [ 1 post ] 
Foreign concepts and OXY: self, namespace, static functions 
Author Message
Yorick Master

Joined: Tue Mar 07, 2006 10:31 pm
Posts: 125
Location: Meudon, France
Post Foreign concepts and OXY: self, namespace, static functions
EDIT: the following are thoughts about what is possible with oxy. Do read the help about oxy, use, save and restore: some things suggested here do not play nice with the intended design of the OXY package.

Hi,

At first (say, for one year or so), I have been very puzzled by how things are designed in OXY. But in the end it's much simpler than it appears. So simple in fact that it's hard to write about it (everything seems obvious... once you have figured it out). This is a rather long post showing how to implement in OXY what you expect from an object oriented package. I know that the gurus here know it all and much more, but I figure that it could be useful for other people (or myself from the future, actually :-) )

SUMMARY:
1) self, this and...use
2) namespace
3) methods, static member functions
4) calling your parent


1) SELF, THIS and... USE
One very simple thing: I was expecting that there should be a way to refer to the current object, like "self" in python, or *this in C++... In OXY, it's essentially "use"! For instance, the following code exhibits 4 ways of accessing the data member of an object (read only):
Code:
func method(void) {
  print, use(data);
  print, use().data;
  self = use(); print, self.data;
  restore, use, data; print, data;
}
object = save(method, data="data");
object, method;

Output:
Code:
> object, method;
"data"
"data"
"data"
"data"


And I know three ways of setting a member from within a method:
Code:
func method(void) {
  save, use, data="0"; print, use(data);
  self = use(); self, data="1"; print, use(data);
  use, data; data="2"; print, data;
}
object = save(method, data="data");
write, format="initial value: %s\n", object.data;
object, method;
write, format="final value: %s\n", object.data;


2) NAMESPACE
If you only put functions in your object, and these functions don't use "use", your object really behaves like a namespace:
Code:
scratch=save(scratch, pkg_fcn1, pkg_fcn2);
func pkg_fcn1(void) {return "fcn1";}
func pkg_fcn2(void) {
  write, format="fcn2 calling pkg.%s\n", pkg.fcn1();
  restore, pkg;
  write, format="fcn2 calling %s\n", fcn1();
}
pkg=save(fcn1=pkg_fcn1, fcn2=pkg_fcn2);
restore, scratch;
pkg.fcn2;

Output:
Code:
> pkg.fcn2;
fcn2 calling pkg.fcn1
fcn2 calling fcn1


3) METHODS, STATIC MEMBER FUNCTIONS
So whether a function "fcn" in an oxy group is a "function" or a "method" only depends on whether or not the special word "use" is used anywhere in the body of the function. Every method in an object is inherently "virtual" in that the user always has the ability to override it. A "static member function" would be a function defined in the class, but not in each instance. Example is better than talk:
Code:
scratch = save(scratch, class_new, class_method,
               class_static_virtual_fcn, class_static_fcn, );

func class_new(member1=, member2=) {
  restore, use, method, static_virtual_fcn;
  return save(member1, member2, method, static_virtual_fcn);
  // static_fcn is not even exported to the instance
}

func class_method(params) {
  restore, use, member1, member2, static_virtual_fcn;
  // does things, using values local to the instance
  // always called as instance(method, params)
}

func class_static_virtual_fcn(param) {
  // does not use other members, but may be overriden locally
  // always called as instance.static_virtual_fcn()
}

func class_static_fcn(params) {
  // does not use anything in the object,
  // always called as class.static_fcn()
}

class = save(new=                class_new,
             method=             class_method,
             static_virtual_fcn= class_static_virtual_fcn,
             static_fcn=         class_static_fcn);
restore, scratch;

instance = class(new, );


4) CALLING YOUR PARENT
Can a child access members from its parents? Well, yes it can:
Code:
func child_print_dad_name(void) {
  restore, use, dad;
  write, format="My dad's name is %s\n", dad.name;
}
func dad_connect_child(child) {
  child, dad=use();
  save, use, child=child;
}
daddy = save(connect_child=dad_connect_child, name="unknown");
child = save(print_dad_name=child_print_dad_name, dad=);
daddy, connect_child, child;
daddy, name="John";
noop, daddy.child(print_dad_name,);

Output:
Code:
> noop, daddy.child(print_dad_name,);
My dad's name is John


Thu Mar 15, 2012 6:03 am
Profile WWW
Display posts from previous:  Sort by  
Reply to topic   [ 1 post ] 

Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by STSoftware for PTF.