Hi,
I asked this once on general Pike list, nobody answered, so I'll try here :) The question is - why create() is called when module is inherited, not when it is instaniated?
If there is Parent.pmod (with create() defined), and Child.pmod, which inherits Parent, then create() defined in Parent will be called when Child is _compiled_. Compilation of Parent won't call it's create() method. In case if module is _imported_, such behavior is logical, but when inherited... What especially confuses me is the fact that regular parent class definition won't cause such effect...
Any ideas/explanations? :) Is this "behavior by design" or? Regards, /Al
The question is - why create() is called when module is inherited, not when it is instaniated?
1) If you inherit modules, you're probably doing something that you really didn't want to do, since modules are objects, not classes.
2) create *is* called when a module is instantiated. Create is called in every object that is instantiated, and modules are objects.
If there is Parent.pmod (with create() defined), and Child.pmod, which inherits Parent, then create() defined in Parent will be called when Child is _compiled_.
That is because you're inheriting an object. .pmod files will be instantiated. You probably don't want to inherit an object. Create is called because Parent.pmod is instantiated to the module object.
Rename Parent.pmod to Parent.pike if you really want to inherit it. .pike files represent classes (programs).
/ Mirar
Previous text:
2004-02-02 09:53: Subject: Pike module initialization at compile time
Hi,
I asked this once on general Pike list, nobody answered, so I'll try here :)
The question is - why create() is called when module is inherited, not when it is instaniated?
If there is Parent.pmod (with create() defined), and Child.pmod, which inherits Parent, then create() defined in Parent will be called when Child is _compiled_. Compilation of Parent won't call it's create() method.
In case if module is _imported_, such behavior is logical, but when inherited... What especially confuses me is the fact that regular parent class definition won't cause such effect...
Any ideas/explanations? :) Is this "behavior by design" or?
Regards, /Al
/ Brevbäraren
On Mon, Feb 02, 2004 at 10:05:01AM +0100, Mirar @ Pike developers forum wrote:
- If you inherit modules, you're probably doing something that you really didn't want to do, since modules are objects, not classes.
OK, then it leads to another question - if modules are objects, why I can't modify variables, defined in those modules (directly)? And what _exactly_ happening when I import or inherit the module (the docs are a bit short in this topic)?
Rename Parent.pmod to Parent.pike if you really want to inherit it. .pike files represent classes (programs).
OK, this works - thank you :)
But there is another question, then...
I've a module with "global" object, initialized to 0. When I try to compile some file, which imports this module, I get an error:
=> Global.pmod <= GlobalClass Global;
class GlobalClass { string method() { return "I am Global!"; } }
void Global_init() { Global = GlobalClass(); }
=> x.pike <= import Global;
int main() { Global_init(); write("Global's value: %O\n", Global->method()); } ============
So, attempt to compile & run: "pike -M. x.pike" gives:
x.pike:7:Indexing on illegal type. (This is Global->method()) Pike: Failed to compile script: Compilation failed.
Well... Frankly, I see no reason why it cannot be _compiled_... When Global is initialized in place (...Global = GlobalClass()), everything is OK.
Regards, /Al
OK, then it leads to another question - if modules are objects, why I can't modify variables, defined in those modules (directly)? And what _exactly_ happening when I import or inherit the module (the docs are a bit short in this topic)?
I'm not really sure. ;)
I don't know if there is a difference between inheriting objects and inheriting the object_program(object). Ie, you will inherit the objects program and thus get your own set of variables.
Module variables can be modified, but are assumed to be constants at compile-time. Ie,
int x=17; ... x=42; // at a later stage
yourmodule.x will here be 17 in some compilations and 42 in later. And never change where you use it outside the module.
int main() { Global_init(); write("Global's value: %O\n", Global->method()); }
See above. Modules are just there to give namespace. If you really want to do this (and have a global object), you need a query method to get the global object every time.
Ie,
object TheGlobal() { return Global; } ... write("Global's value: %O\n", TheGlobal()->method());
There is no use in accessing variables in modules from outside the module.
You *can* however instantiate the Global object when the module is created, like this:
object Global=GlobalClass();
and use it as a *constant*.
/ Mirar
Previous text:
2004-02-02 10:30: Subject: Re: Pike module initialization at compile time
On Mon, Feb 02, 2004 at 10:05:01AM +0100, Mirar @ Pike developers forum wrote:
- If you inherit modules, you're probably doing something that you really didn't want to do, since modules are objects, not classes.
OK, then it leads to another question - if modules are objects, why I can't modify variables, defined in those modules (directly)? And what _exactly_ happening when I import or inherit the module (the docs are a bit short in this topic)?
Rename Parent.pmod to Parent.pike if you really want to inherit it. .pike files represent classes (programs).
OK, this works - thank you :)
But there is another question, then...
I've a module with "global" object, initialized to 0. When I try to compile some file, which imports this module, I get an error:
=> Global.pmod <= GlobalClass Global;
class GlobalClass { string method() { return "I am Global!"; } }
void Global_init() { Global = GlobalClass(); }
=> x.pike <= import Global;
int main() { Global_init(); write("Global's value: %O\n", Global->method()); } ============
So, attempt to compile & run: "pike -M. x.pike" gives:
x.pike:7:Indexing on illegal type. (This is Global->method()) Pike: Failed to compile script: Compilation failed.
Well... Frankly, I see no reason why it cannot be _compiled_... When Global is initialized in place (...Global = GlobalClass()), everything is OK.
Regards, /Al
/ Brevbäraren
On Mon, Feb 02, 2004 at 10:40:02AM +0100, Mirar @ Pike developers forum wrote:
Module variables can be modified, but are assumed to be constants at compile-time. Ie,
But they can't be modified (and accessed directly) _outside_, however.
See above. Modules are just there to give namespace. If you really want to do this (and have a global object), you need a query method to get the global object every time.
It is more logical (IMHO, of course) to access some "global" (i.e. defined in module) variable by using syntax like Module.var, rather than Module.var() - which is a bit misleading. Also, it would be nice to have possibility to _modify_ such variable simply by using Module.var = "value", but it seems that language doesn't allow such accesses.
And, according to your explanation, _anything_ that is defined in module is a constant, which is different to declaration (and to class declaration as well).
There is no use in accessing variables in modules from outside the module.
Why not? I can access variables in objects, and module is an object, or?
Well, I know that it is good practice - to access object's internals through methods, but again... Syntax... Something like "properties" (which was discussed some time ago) would solve this problem...
Sometimes I hate to use `->() and `->=() to define only few "properties" (this looks confusing to anyone who is not familiar with Pike).
Regards, /Al
And, according to your explanation, _anything_ that is defined in module is a constant, which is different to declaration (and to class declaration as well).
Yes. Compare to add_constant. A module name is not to be treated like an object variable. A module is just adding more namespace to the add_constant compilation time namespace.
/ Mirar
Previous text:
2004-02-02 11:08: Subject: Re: Pike module initialization at compile time
On Mon, Feb 02, 2004 at 10:40:02AM +0100, Mirar @ Pike developers forum wrote:
Module variables can be modified, but are assumed to be constants at compile-time. Ie,
But they can't be modified (and accessed directly) _outside_, however.
See above. Modules are just there to give namespace. If you really want to do this (and have a global object), you need a query method to get the global object every time.
It is more logical (IMHO, of course) to access some "global" (i.e. defined in module) variable by using syntax like Module.var, rather than Module.var() - which is a bit misleading. Also, it would be nice to have possibility to _modify_ such variable simply by using Module.var = "value", but it seems that language doesn't allow such accesses.
And, according to your explanation, _anything_ that is defined in module is a constant, which is different to declaration (and to class declaration as well).
There is no use in accessing variables in modules from outside the module.
Why not? I can access variables in objects, and module is an object, or?
Well, I know that it is good practice - to access object's internals through methods, but again... Syntax... Something like "properties" (which was discussed some time ago) would solve this problem...
Sometimes I hate to use `->() and `->=() to define only few "properties" (this looks confusing to anyone who is not familiar with Pike).
Regards, /Al
/ Brevbäraren
Well, it's a bit misleading to say that module variables are generally assumed to be constants at compile time. They are variables, but the '.' operator is evaluated at compile time, so anything indexed through it becomes a constant value.
As for imports, any identifier it adds are accessed as through a '.' operator, so they become constants too.
/.../ If you really want to do this (and have a global object), you need a query method to get the global object every time.
No, it's enough to index the module with '->' instead. Al's example with a module and a variable inside it with the same name makes it unnecessarily confusing, so I prove another example:
Foo.pmod:
int var = 17;
foo.pike:
import "."; int main () { werror ("%O\n", Foo.var); // writes 17 Foo->var = 42; werror ("%O\n", Foo.var); // still writes 17 werror ("%O\n", Foo->var); // writes 42 }
(I import '.' instead of '.Foo' to more clearly show the relation between '.' and '->'.)
/ Martin Stjernholm, Roxen IS
Previous text:
2004-02-02 10:37: Subject: Re: Pike module initialization at compile time
OK, then it leads to another question - if modules are objects, why I can't modify variables, defined in those modules (directly)? And what _exactly_ happening when I import or inherit the module (the docs are a bit short in this topic)?
I'm not really sure. ;)
I don't know if there is a difference between inheriting objects and inheriting the object_program(object). Ie, you will inherit the objects program and thus get your own set of variables.
Module variables can be modified, but are assumed to be constants at compile-time. Ie,
int x=17; ... x=42; // at a later stage
yourmodule.x will here be 17 in some compilations and 42 in later. And never change where you use it outside the module.
int main() { Global_init(); write("Global's value: %O\n", Global->method()); }
See above. Modules are just there to give namespace. If you really want to do this (and have a global object), you need a query method to get the global object every time.
Ie,
object TheGlobal() { return Global; } ... write("Global's value: %O\n", TheGlobal()->method());
There is no use in accessing variables in modules from outside the module.
You *can* however instantiate the Global object when the module is created, like this:
object Global=GlobalClass();
and use it as a *constant*.
/ Mirar
Well, it's a bit misleading to say that module variables are generally assumed to be constants at compile time. They are variables, but the '.' operator is evaluated at compile time, so anything indexed through it becomes a constant value.
Well, "int x" in a module is ok to use as a constant value,
-- test.pmod: int x=17; ... import test; constant bar=x;
is totally ok. So they *are* seen as constants.
No, it's enough to index the module with '->' instead.
Ah, interesting. I didn't know that.
/ Mirar
Previous text:
2004-02-02 22:11: Subject: Re: Pike module initialization at compile time
Well, it's a bit misleading to say that module variables are generally assumed to be constants at compile time. They are variables, but the '.' operator is evaluated at compile time, so anything indexed through it becomes a constant value.
As for imports, any identifier it adds are accessed as through a '.' operator, so they become constants too.
/.../ If you really want to do this (and have a global object), you need a query method to get the global object every time.
No, it's enough to index the module with '->' instead. Al's example with a module and a variable inside it with the same name makes it unnecessarily confusing, so I prove another example:
Foo.pmod:
int var = 17;
foo.pike:
import "."; int main () { werror ("%O\n", Foo.var); // writes 17 Foo->var = 42; werror ("%O\n", Foo.var); // still writes 17 werror ("%O\n", Foo->var); // writes 42 }
(I import '.' instead of '.Foo' to more clearly show the relation between '.' and '->'.)
/ Martin Stjernholm, Roxen IS
Conceptually you still have a '.' operator that causes the value to be constant. It's just that it's implied by the import for all its imported identifiers - an import is nothing more than a convenience to avoid writing "Whatever." in front of all the identifiers.
/ Martin Stjernholm, Roxen IS
Previous text:
2004-02-02 22:18: Subject: Re: Pike module initialization at compile time
Well, it's a bit misleading to say that module variables are generally assumed to be constants at compile time. They are variables, but the '.' operator is evaluated at compile time, so anything indexed through it becomes a constant value.
Well, "int x" in a module is ok to use as a constant value,
-- test.pmod: int x=17; ... import test; constant bar=x;
is totally ok. So they *are* seen as constants.
No, it's enough to index the module with '->' instead.
Ah, interesting. I didn't know that.
/ Mirar
On Mon, Feb 02, 2004 at 10:15:01PM +0100, Martin Stjernholm, Roxen IS @ Pike developers forum wrote:
assumed to be constants at compile time. They are variables, but the '.' operator is evaluated at compile time, so anything indexed through it becomes a constant value.
Ahhh.... Now I see.... By importing something I just add implicit "Foo." to anything what otherwise would have Foo. as prefix...
It also means that I've to use Foo->var always to access some module's variable directly, and there is no way to remove this "Foo->" prefix...
...so I am going to miss (again) `=() - to access module variables directly :)
Regards, /Al
On Mon, Feb 02, 2004 at 10:05:01AM +0100, Mirar @ Pike developers forum wrote:
Rename Parent.pmod to Parent.pike if you really want to inherit it. .pike files represent classes (programs).
Well... Seems that I am doing something wrong... Again, two files - Parent.pike and Child.pike, where Child.pike contains:
--snip-- inherit Parent;
//blabla --snip--
Both files in same directory, but when I do "pike -M. Child.pike" I get:
Child.pike:1:Illegal program pointer.
When I use "inherit .Parent" - everything is OK. So, what I am doing wrong here? :)
Regards, /Al
Hmm. It probably doesn't search your directory if you don't explicit say ".Parent" or do import "."; above the inherit.
/ Mirar
Previous text:
2004-02-02 11:49: Subject: Re: Pike module initialization at compile time
On Mon, Feb 02, 2004 at 10:05:01AM +0100, Mirar @ Pike developers forum wrote:
Rename Parent.pmod to Parent.pike if you really want to inherit it. .pike files represent classes (programs).
Well... Seems that I am doing something wrong... Again, two files - Parent.pike and Child.pike, where Child.pike contains:
--snip-- inherit Parent;
//blabla --snip--
Both files in same directory, but when I do "pike -M. Child.pike" I get:
Child.pike:1:Illegal program pointer.
When I use "inherit .Parent" - everything is OK. So, what I am doing wrong here? :)
Regards, /Al
/ Brevbäraren
On Mon, Feb 02, 2004 at 12:10:03PM +0100, Mirar @ Pike developers forum wrote:
Hmm. It probably doesn't search your directory if you don't explicit say ".Parent" or do import "."; above the inherit.
Hmm... Is it bug or feature? :) And what will be done when I specify
import ".";
- will it import all (.pike & .pmod) files from the directory or will use the directory to resolve names only?
Regards, /Al
Hmm... Is it bug or feature? :) And what will be done when I specify
import ".";
- will it import all (.pike & .pmod) files from the directory or will
use the directory to resolve names only?
What would be the difference? import is a namespace operation.
Regards, /Al
/ Henrik Grubbström (Lysator)
Previous text:
2004-02-02 12:37: Subject: Re: Pike module initialization at compile time
On Mon, Feb 02, 2004 at 12:10:03PM +0100, Mirar @ Pike developers forum wrote:
Hmm. It probably doesn't search your directory if you don't explicit say ".Parent" or do import "."; above the inherit.
Hmm... Is it bug or feature? :) And what will be done when I specify
import ".";
- will it import all (.pike & .pmod) files from the directory or will
use the directory to resolve names only?
Regards, /Al
/ Brevbäraren
On Mon, Feb 02, 2004 at 01:15:02PM +0100, Henrik Grubbstrцm (Lysator) @ Pike (-) developers forum wrote:
What would be the difference? import is a namespace operation.
Hmm... If import is namespace operation, why (then) code is executed during this operation? Or it is executed only for .pmod files?
The question, actually, is - which files (.pmod and/or .pike) import "." will use... And - where. And which location inherit uses to search for programs/modules...
Regards, /Al
Hmm... If import is namespace operation, why (then) code is executed during this operation? Or it is executed only for .pmod files?
The foo.pmod code is loaded, compiled and instantiated by the compiler, druing the compilation of code that refers to the module.
The question, actually, is - which files (.pmod and/or .pike) import "." will use... And - where. And which location inherit uses to search for programs/modules...
To inherit a file bar.pike in the same directory, simply use
inherit .bar;
If you don't want to type the dot there, you can use
import .; ... inherit bar;
which will do about the same thing, except that the compiler will look in your directory for *all* modules. So if you for example happen to have a file Stdio.pmod in that directory, the compiler will pick it up instead of the standard Stdio module. That's why import . is not really recommended.
/ Niels Möller (vässar rödpennan)
Previous text:
2004-02-02 13:39: Subject: Re: Pike module initialization at compile time
On Mon, Feb 02, 2004 at 01:15:02PM +0100, Henrik Grubbström (Lysator) @ Pike (-) developers forum wrote:
What would be the difference? import is a namespace operation.
Hmm... If import is namespace operation, why (then) code is executed during this operation? Or it is executed only for .pmod files?
The question, actually, is - which files (.pmod and/or .pike) import "." will use... And - where. And which location inherit uses to search for programs/modules...
Regards, /Al
/ Brevbäraren
Hmm... If import is namespace operation, why (then) code is executed during this operation? Or it is executed only for .pmod files?
Code is executed when the corresponding directory module is resolved.
The question, actually, is - which files (.pmod and/or .pike) import "." will use... And - where. And which location inherit uses to search
import "." creates a directory module of the directory the current source file is in, and imports that module. See handle_import() for details.
for programs/modules...
The default implementation of handle_inherit() uses cast_to_program(), which in turn searches the directory the current file is in, and then the program path as specified by ${PIKE_PROGRAM_PATH} and -P.
Regards, /Al
/ Henrik Grubbström (Lysator)
Previous text:
2004-02-02 13:39: Subject: Re: Pike module initialization at compile time
On Mon, Feb 02, 2004 at 01:15:02PM +0100, Henrik Grubbström (Lysator) @ Pike (-) developers forum wrote:
What would be the difference? import is a namespace operation.
Hmm... If import is namespace operation, why (then) code is executed during this operation? Or it is executed only for .pmod files?
The question, actually, is - which files (.pmod and/or .pike) import "." will use... And - where. And which location inherit uses to search for programs/modules...
Regards, /Al
/ Brevbäraren
On Mon, Feb 02, 2004 at 01:55:07PM +0100, Henrik Grubbström (Lysator) @ Pike (-) developers forum wrote:
The default implementation of handle_inherit() uses cast_to_program(), which in turn searches the directory the current file is in, and then the program path as specified by ${PIKE_PROGRAM_PATH} and -P.
Then it seems strange why "inherit Parent;" doesn't work when Parent.pike is in the same directory where compiled file is... I tried -P. and -M. - it doesn't work, so I use "import .;" instead...
BTW, do I understand it correctly - i.e., I can specify any directory name for import, so it will be used like -M & -P flags?
Regards, /Al
Then it seems strange why "inherit Parent;" doesn't work when Parent.pike is in the same directory where compiled file is... I tried -P. and -M. - it doesn't work, so I use "import .;" instead...
-P. is NOT the same as import ".". -P is relative to cwd, while import "." is relative to the current file.
BTW, do I understand it correctly - i.e., I can specify any directory name for import, so it will be used like -M & -P flags?
Yes.
Regards, /Al
/ Henrik Grubbström (Lysator)
Previous text:
2004-02-02 14:38: Subject: Re: Pike module initialization at compile time
On Mon, Feb 02, 2004 at 01:55:07PM +0100, Henrik Grubbström (Lysator) @ Pike (-) developers forum wrote:
The default implementation of handle_inherit() uses cast_to_program(), which in turn searches the directory the current file is in, and then the program path as specified by ${PIKE_PROGRAM_PATH} and -P.
Then it seems strange why "inherit Parent;" doesn't work when Parent.pike is in the same directory where compiled file is... I tried -P. and -M. - it doesn't work, so I use "import .;" instead...
BTW, do I understand it correctly - i.e., I can specify any directory name for import, so it will be used like -M & -P flags?
Regards, /Al
/ Brevbäraren
pike-devel@lists.lysator.liu.se