Search code examples
rakumeta-object-protocol

Changing a class variable from outside the class


Finally, when I managed to understand how to fix this, that is, how to change the value of an internal dynamic variable, the code has moved on and now it is declared in this way:

my int $is-win = Rakudo::Internals.IS-WIN;

This is a class variable declared inside class Encoding::Builtin. Makes all the sense in the world, since an OS is not something that changes during the lifetime of a variable. However, I need to test this code from other OS, so I would need to access that class variable and assign it a True value. Can I do that using the meta object protocol?


Solution

  • The concept of "class variable" doesn't exist in Perl 6.

    The declaration being considered is of a lexical variable, and its lifetime is bound to the scope (bounded by curly braces) that it is declared within. It doesn't have any relationship with the class that's being declared, so there's no way to reach it through the MOP. (That the block in this question happens to be attached to a class declaration is incidental so far as lexical variables go.) Nor is it declared our, so it's not stored in the package either.

    The only way a lexical can be accessed - aside from under a debugger - is if something inside of that lexical scope explicitly made it possible (for example, by acquiring a pseudo-package and storing it somewhere more widely visible, or by allowing EVAL of provided code). Neither is happening in this case, so the variable not possible to access.

    Perl 6 is very strict about lexical scoping, and that's a very intentional part of the language design. It supports the user in understanding and refactoring the program, and the compiler in program analysis and optimization. Put another way, Perl 6 is a fairly static language when it comes to lexical things (and will likely come to do much more static analysis in future language versions), and a dynamic language when it comes to object things.