It's been a while since I did any cmods, but now I need to write one for work related stuff. All questions are in the context of late CVS 7.7.
Q1: How should I define my classes to get the following function:
indices(Foo);
({ get_bar })
object x = Foo(); indices(x);
({ get_bar })
get_bar();
Foo.bar();
Ie, I want a class within Foo that can only be instantiated using the Foo.get_bar() method.
Q2: Is there a way that a Foo.bar() object (as described above) can access the variables defined in Foo? (The variables which are accessed thru the THIS-pointer that is.)
References to where things like this is already done within the Pike-source is appreciated.
Q1: How should I define my classes to get the following function:
[...]
Ie, I want a class within Foo that can only be instantiated using the Foo.get_bar() method.
I'm not quite sure what you mean by "can only".
The following might do what you want:
Foo.pmod:
static class bar {}; bar get_bar() { return bar(); }
Equvivalent cmod:
PIKECLASS bar flags ID_STATIC; { }
PIKEFUN object(bar) get_bar() { pop_n_elems(args); push_object(clone_object(bar_program, 0)); }
Q2: Is there a way that a Foo.bar() object (as described above) can access the variables defined in Foo? (The variables which are accessed thru the THIS-pointer that is.)
You mean via the parent-pointer.
Yes (of course, since everything that can be done at Pike-level, by definition can be done at C-level).
Something like the following ought to work:
PIKEVAR mixed foo;
PIKECLASS bar { PIKEFUN get_foo() { struct external_variable_context loc;
pop_n_elems(args);
loc.o = Pike_fp->current_object; loc.parent_identifier = Pike_fp->fun; if (loc.o->prog) loc.inherit = INHERIT_FROM_INT(loc.o->prog, loc.parent_identifier); find_external_context(&loc, 1);
low_object_index_no_free(Pike_sp, loc.o, foo_var_num + loc.inherit->identifier_level); Pike_sp++; } }
Getting the value for foo_var_num is left as an exercise. :-)
References to where things like this is already done within the Pike-source is appreciated.
interpret_functions.h contains lots of interesting code...
/ Henrik Grubbström (Lysator)
Previous text:
2004-08-13 07:22: Subject: CMOD questions
It's been a while since I did any cmods, but now I need to write one for work related stuff. All questions are in the context of late CVS 7.7.
Q1: How should I define my classes to get the following function:
indices(Foo);
({ get_bar })
object x = Foo(); indices(x);
({ get_bar })
get_bar();
Foo.bar();
Ie, I want a class within Foo that can only be instantiated using the Foo.get_bar() method.
Q2: Is there a way that a Foo.bar() object (as described above) can access the variables defined in Foo? (The variables which are accessed thru the THIS-pointer that is.)
References to where things like this is already done within the Pike-source is appreciated.
/ Marcus Agehall (PacketFront)
Thank you. Just what I needed.
/ Marcus Agehall (PacketFront)
Previous text:
2004-08-13 10:54: Subject: CMOD questions
Q1: How should I define my classes to get the following function:
[...]
Ie, I want a class within Foo that can only be instantiated using the Foo.get_bar() method.
I'm not quite sure what you mean by "can only".
The following might do what you want:
Foo.pmod:
static class bar {}; bar get_bar() { return bar(); }
Equvivalent cmod:
PIKECLASS bar flags ID_STATIC; { }
PIKEFUN object(bar) get_bar() { pop_n_elems(args); push_object(clone_object(bar_program, 0)); }
Q2: Is there a way that a Foo.bar() object (as described above) can access the variables defined in Foo? (The variables which are accessed thru the THIS-pointer that is.)
You mean via the parent-pointer.
Yes (of course, since everything that can be done at Pike-level, by definition can be done at C-level).
Something like the following ought to work:
PIKEVAR mixed foo;
PIKECLASS bar { PIKEFUN get_foo() { struct external_variable_context loc;
pop_n_elems(args);
loc.o = Pike_fp->current_object; loc.parent_identifier = Pike_fp->fun; if (loc.o->prog) loc.inherit = INHERIT_FROM_INT(loc.o->prog, loc.parent_identifier); find_external_context(&loc, 1);
low_object_index_no_free(Pike_sp, loc.o, foo_var_num + loc.inherit->identifier_level); Pike_sp++; } }
Getting the value for foo_var_num is left as an exercise. :-)
References to where things like this is already done within the Pike-source is appreciated.
interpret_functions.h contains lots of interesting code...
/ Henrik Grubbström (Lysator)
What is foo_var_num supposed to be in your second example?
Also, the ID_STATIC flag was close to what I wanted. When using it, the inner class is invisible to index() when applied to an object but not when doing something like index(Foo.Bar).
I would like to get the following:
indices(Foo.Bar);
({ methods ... })
indices(Foo.Bar());
({ Gazonk methods ... })
Ie, the important thing is that when Gazonk is instantiated, there is a surrounding instance which has initialized some things.
/ Marcus Agehall (PacketFront)
Previous text:
2004-08-13 10:54: Subject: CMOD questions
Q1: How should I define my classes to get the following function:
[...]
Ie, I want a class within Foo that can only be instantiated using the Foo.get_bar() method.
I'm not quite sure what you mean by "can only".
The following might do what you want:
Foo.pmod:
static class bar {}; bar get_bar() { return bar(); }
Equvivalent cmod:
PIKECLASS bar flags ID_STATIC; { }
PIKEFUN object(bar) get_bar() { pop_n_elems(args); push_object(clone_object(bar_program, 0)); }
Q2: Is there a way that a Foo.bar() object (as described above) can access the variables defined in Foo? (The variables which are accessed thru the THIS-pointer that is.)
You mean via the parent-pointer.
Yes (of course, since everything that can be done at Pike-level, by definition can be done at C-level).
Something like the following ought to work:
PIKEVAR mixed foo;
PIKECLASS bar { PIKEFUN get_foo() { struct external_variable_context loc;
pop_n_elems(args);
loc.o = Pike_fp->current_object; loc.parent_identifier = Pike_fp->fun; if (loc.o->prog) loc.inherit = INHERIT_FROM_INT(loc.o->prog, loc.parent_identifier); find_external_context(&loc, 1);
low_object_index_no_free(Pike_sp, loc.o, foo_var_num + loc.inherit->identifier_level); Pike_sp++; } }
Getting the value for foo_var_num is left as an exercise. :-)
References to where things like this is already done within the Pike-source is appreciated.
interpret_functions.h contains lots of interesting code...
/ Henrik Grubbström (Lysator)
What is foo_var_num supposed to be in your second example?
That's the exercise. :-)
Hint: It's a run-time constant similar to get_bar_fun_num.
Also, the ID_STATIC flag was close to what I wanted. When using it, the inner class is invisible to index() when applied to an object but not when doing something like index(Foo.Bar).
?
I would like to get the following:
indices(Foo.Bar);
({ methods ... })
indices(Foo.Bar());
({ Gazonk methods ... })
Ok, so Foo.Bar is an object with an lfun::`()() that returns a Gazonk object?
Ie, the important thing is that when Gazonk is instantiated, there is a surrounding instance which has initialized some things.
I don't see what your example has to do with the above statement.
/ Henrik Grubbström (Lysator)
Previous text:
2004-08-13 13:20: Subject: CMOD questions
What is foo_var_num supposed to be in your second example?
Also, the ID_STATIC flag was close to what I wanted. When using it, the inner class is invisible to index() when applied to an object but not when doing something like index(Foo.Bar).
I would like to get the following:
indices(Foo.Bar);
({ methods ... })
indices(Foo.Bar());
({ Gazonk methods ... })
Ie, the important thing is that when Gazonk is instantiated, there is a surrounding instance which has initialized some things.
/ Marcus Agehall (PacketFront)
Ah, ok I'll do my homework then.. ;)
I don't think that I want an lfun::`()() that returns a Gazonk-object in Foo.Bar.
I think I'm explaining this wrong. Here is another attempt:
I have a library to which I'm trying to create an interface. The library has a general part and several "submodules".
I want to make the glue so that the user first creates an object Foo() from the program Foo. Then, from Foo(), the user may create other objects which uses the general parts as set up in Foo().
Therefore, the user must not do Foo.Bar() directly. She should only be able to do Foo()->Bar() or something similar such as Foo()->get_bar() to create Bar-objects.
Did that clarify what I wish to do? Using the ID_STATIC flag on the Bar program still shows Bar when doing indices(Foo) but does not allow Foo()->Bar(). Is there a way of solving this?
/ Marcus Agehall (PacketFront)
Previous text:
2004-08-13 13:29: Subject: CMOD questions
What is foo_var_num supposed to be in your second example?
That's the exercise. :-)
Hint: It's a run-time constant similar to get_bar_fun_num.
Also, the ID_STATIC flag was close to what I wanted. When using it, the inner class is invisible to index() when applied to an object but not when doing something like index(Foo.Bar).
?
I would like to get the following:
indices(Foo.Bar);
({ methods ... })
indices(Foo.Bar());
({ Gazonk methods ... })
Ok, so Foo.Bar is an object with an lfun::`()() that returns a Gazonk object?
Ie, the important thing is that when Gazonk is instantiated, there is a surrounding instance which has initialized some things.
I don't see what your example has to do with the above statement.
/ Henrik Grubbström (Lysator)
I have a library to which I'm trying to create an interface. The library has a general part and several "submodules".
Ok.
I want to make the glue so that the user first creates an object Foo() from the program Foo. Then, from Foo(), the user may create other objects which uses the general parts as set up in Foo().
Therefore, the user must not do Foo.Bar() directly. She should only be able to do Foo()->Bar() or something similar such as Foo()->get_bar() to create Bar-objects.
You'll get this enforced by the runtime if Foo.Bar has been tagged as PROGRAM_USES_PARENT.
Did that clarify what I wish to do? Using the ID_STATIC flag on the Bar program still shows Bar when doing indices(Foo) but does not allow Foo()->Bar(). Is there a way of solving this?
I don't believe you. predef::indices() filters static symbols.
/ Henrik Grubbström (Lysator)
Previous text:
2004-08-13 13:45: Subject: CMOD questions
Ah, ok I'll do my homework then.. ;)
I don't think that I want an lfun::`()() that returns a Gazonk-object in Foo.Bar.
I think I'm explaining this wrong. Here is another attempt:
I have a library to which I'm trying to create an interface. The library has a general part and several "submodules".
I want to make the glue so that the user first creates an object Foo() from the program Foo. Then, from Foo(), the user may create other objects which uses the general parts as set up in Foo().
Therefore, the user must not do Foo.Bar() directly. She should only be able to do Foo()->Bar() or something similar such as Foo()->get_bar() to create Bar-objects.
Did that clarify what I wish to do? Using the ID_STATIC flag on the Bar program still shows Bar when doing indices(Foo) but does not allow Foo()->Bar(). Is there a way of solving this?
/ Marcus Agehall (PacketFront)
class Foo { static class Bar { }
object get_bar() { return Bar(); } }
void main() {
write("%O\n", indices(Foo)); write("%O\n", indices(Foo())); write("%O\n", Foo.Bar()); exit(0); }
gives me
({ /* 1 element */ "Bar" }) ({ /* 2 elements */ "get_bar", "Bar" }) /home/marage/src/Pike/pf-7.7/test()->Foo()->Bar()
Perhaps something is broken then, or doesn't the static keyword in pike-code do the same thing as ID_STATIC in cmod?
/ Marcus Agehall (PacketFront)
Previous text:
2004-08-13 14:00: Subject: CMOD questions
I have a library to which I'm trying to create an interface. The library has a general part and several "submodules".
Ok.
I want to make the glue so that the user first creates an object Foo() from the program Foo. Then, from Foo(), the user may create other objects which uses the general parts as set up in Foo().
Therefore, the user must not do Foo.Bar() directly. She should only be able to do Foo()->Bar() or something similar such as Foo()->get_bar() to create Bar-objects.
You'll get this enforced by the runtime if Foo.Bar has been tagged as PROGRAM_USES_PARENT.
Did that clarify what I wish to do? Using the ID_STATIC flag on the Bar program still shows Bar when doing indices(Foo) but does not allow Foo()->Bar(). Is there a way of solving this?
I don't believe you. predef::indices() filters static symbols.
/ Henrik Grubbström (Lysator)
$ ./pike -mmaster.pike lyskom_1253939.pike lyskom_1253939.pike:12:Index "Bar" not present in module "Foo". Pike: Failed to compile script: Compilation failed.
master.pike:2674: master()->_main(({"./pike","-mmaster.pike","lyskom_1253939.pike"}),({"PWD=/ home/grubba/src/Pike/7.7/build/sunos-5.8-sun4u","TZ=MET","ORACLE_SID=TEST" ,"WINDOWID=192937997","PAGER=less","LC_MESSAGES=C",,,41}))
Which is more or less what I expect.
After commenting out line 12, I however get:
$ ./pike -mmaster.pike lyskom_1253939.pike ({ /* 1 element */ "Bar" }) ({ /* 1 element */ "get_bar" })
Which shows a bug in program_indices(). Fixed:
$ ./pike -mmaster.pike lyskom_1253939.pike ({ }) ({ /* 1 element */ "get_bar" })
/ Henrik Grubbström (Lysator)
Previous text:
2004-08-13 14:02: Subject: CMOD questions
class Foo { static class Bar { }
object get_bar() { return Bar(); } }
void main() {
write("%O\n", indices(Foo)); write("%O\n", indices(Foo())); write("%O\n", Foo.Bar()); exit(0); }
gives me
({ /* 1 element */ "Bar" }) ({ /* 2 elements */ "get_bar", "Bar" }) /home/marage/src/Pike/pf-7.7/test()->Foo()->Bar()
Perhaps something is broken then, or doesn't the static keyword in pike-code do the same thing as ID_STATIC in cmod?
/ Marcus Agehall (PacketFront)
Yeah, that looks much more like what I expected too. But since I know that most of the core is written by programmers that are better than me at what they do, I usually assume that I'm doing something wrong.. ;)
/ Marcus Agehall (PacketFront)
Previous text:
2004-08-13 14:22: Subject: CMOD questions
$ ./pike -mmaster.pike lyskom_1253939.pike lyskom_1253939.pike:12:Index "Bar" not present in module "Foo". Pike: Failed to compile script: Compilation failed.
master.pike:2674: master()->_main(({"./pike","-mmaster.pike","lyskom_1253939.pike"}),({"PWD=/ home/grubba/src/Pike/7.7/build/sunos-5.8-sun4u","TZ=MET","ORACLE_SID=TEST" ,"WINDOWID=192937997","PAGER=less","LC_MESSAGES=C",,,41}))
Which is more or less what I expect.
After commenting out line 12, I however get:
$ ./pike -mmaster.pike lyskom_1253939.pike ({ /* 1 element */ "Bar" }) ({ /* 1 element */ "get_bar" })
Which shows a bug in program_indices(). Fixed:
$ ./pike -mmaster.pike lyskom_1253939.pike ({ }) ({ /* 1 element */ "get_bar" })
/ Henrik Grubbström (Lysator)
pike-devel@lists.lysator.liu.se