I am having trouble defining some notation globally. I am trying to define some notation in a scope within a module, and I would like to have it available in other modules, but I cannot make this happen.
For example, if i write
Declare Scope scope0.
Declare Scope scope1.
Declare Scope scope2.
Module A.
Notation ". A" := (list A) (at level 100) : scope0.
#[global]
Notation ". A" := (list A) (at level 100) : scope1.
#[local]
Notation ". A" := (list A) (at level 100) : scope2.
Print Scope scope0.
Print Scope scope1.
Print Scope scope2.
End A.
Module B.
Print Scope scope0.
Print Scope scope1.
Print Scope scope2.
End B.
Then the three first Print Scope shows that the notation is present in the scope, but in the last three ones it is gone again, and I cannot use it.
When I read the documentation of Notation I got the impression that it should not be local to a module.
I found the answer, namely that I should import the module after closing it. That is, with
Declare Scope scope0.
Module A.
Notation ". A" := (list A) (at level 100) : scope0.
End A.
Import A.
Module B.
Print Scope scope0.
End B
The notation is also available in module B, and the Print Scope statement lists it.
I found it by reading about the Import command where is says:
Some features defined in modules are activated only when a module is imported. This is for instance the case of notations (see Notations).
and gave examples where modules were imported right after they were closed.
There might be other ways of doing it, but this was the one I found.
As a principle, things defined in a module are not available outside of it unless you Require/Import the module to make it available in scope.
The distinction between local and global—unless I'm mistaken—is more related to what is indeed available outside of the module when it is imported.
In the case of notations you have to import the module for them to be available. So you would need
Import A.
in your module B.
Related
In perl special tokens like __PACKAGE__, __SUB__, __FILE__, __LINE__ exists and available from script.
I may get value of __PACKAGE__ from XS as HvNAME( PL_currstash ), I suppose.
But how to access others?
Is there special interface to access all of them from XS? Like: CTX->package, CTX->sub etc.
You can look them up one by one in toke.c for the compile-time values:
__PACKAGE__ => HvNAME(PL_curstash) or PL_curstname
__FILE__ => CopFILE(PL_curcop) (at compile-time)
__LINE__ => CopLINE(PL_curcop) (at compile-time)
__SUB__ => PL_compcv
If you need them at run-time look at the various data fields available in the context caller_cx and current sub (cv). There's no context struct as in parrot or perl6 passed around, rather a stack of active context blocks.
Perl subroutines are represented in C with type CV. The CV for the XSUB is passed in the cv argument:
#define XSPROTO(name) void name(pTHX_ CV* cv)
You can get the name of the XSUB with GvNAME(CvGV(cv)). This is especially useful if you register an XSUB under multiple names, for example with the ALIAS or INTERFACE keywords, or in typemaps.
To get the current stash (__PACKAGE__ equivalent), I'd suggest to use CvSTASH(cv).
__FILE__ and __LINE__ are provided by the C compiler as macro.
The C equivalent to __FILE__ is __FILE__.
The C equivalent to __LINE__ is __LINE__.
The C99 equivalent to __SUB__ is __func__. There wasn't anything standard before.
There's no C equivalent to __PACKAGE__ because C doesn't have namespaces.
That said, I don't think you want information about the current line of execution; I think you want information about the XS sub's caller. That means you're actually asking for the XS equivalent of caller.
The XS equivalent of caller is caller_cx. Looking at Perl_cx_dump in scope.c should give an idea how to use the returned PERL_CONTEXT structure.
In perl special tokens like __PACKAGE__, __SUB__, __FILE__, __LINE__ exists and available from script.
I may get value of __PACKAGE__ from XS as HvNAME( PL_currstash ), I suppose.
But how to access others?
Is there special interface to access all of them from XS? Like: CTX->package, CTX->sub etc.
You can look them up one by one in toke.c for the compile-time values:
__PACKAGE__ => HvNAME(PL_curstash) or PL_curstname
__FILE__ => CopFILE(PL_curcop) (at compile-time)
__LINE__ => CopLINE(PL_curcop) (at compile-time)
__SUB__ => PL_compcv
If you need them at run-time look at the various data fields available in the context caller_cx and current sub (cv). There's no context struct as in parrot or perl6 passed around, rather a stack of active context blocks.
Perl subroutines are represented in C with type CV. The CV for the XSUB is passed in the cv argument:
#define XSPROTO(name) void name(pTHX_ CV* cv)
You can get the name of the XSUB with GvNAME(CvGV(cv)). This is especially useful if you register an XSUB under multiple names, for example with the ALIAS or INTERFACE keywords, or in typemaps.
To get the current stash (__PACKAGE__ equivalent), I'd suggest to use CvSTASH(cv).
__FILE__ and __LINE__ are provided by the C compiler as macro.
The C equivalent to __FILE__ is __FILE__.
The C equivalent to __LINE__ is __LINE__.
The C99 equivalent to __SUB__ is __func__. There wasn't anything standard before.
There's no C equivalent to __PACKAGE__ because C doesn't have namespaces.
That said, I don't think you want information about the current line of execution; I think you want information about the XS sub's caller. That means you're actually asking for the XS equivalent of caller.
The XS equivalent of caller is caller_cx. Looking at Perl_cx_dump in scope.c should give an idea how to use the returned PERL_CONTEXT structure.
I am new to Perl and I have been following a book. All is well, except for whenever I try to initialize a variable as shown by the book, I am getting an error like below. Kindly tell me what should I do in order to avoid this error?
Code:
#!/usr/bin/perl -w
use 5.014;
use strict;
use utf8;
$radius = <STDIN>;
$circum;
if ($radius<0){
$circum = 0
} else{
$circum = 2*3.141*$radius;
}
print $circum."\n";
Errors:
Global symbol "$radius" requires explicit package name at ./example1 line 6.
Global symbol "$circum" requires explicit package name at ./example1 line 7.
Global symbol "$radius" requires explicit package name at ./example1 line 8.
Global symbol "$circum" requires explicit package name at ./example1 line 9.
Global symbol "$circum" requires explicit package name at ./example1 line 11.
Global symbol "$radius" requires explicit package name at ./example1 line 11.
Global symbol "$circum" requires explicit package name at ./example1 line 14.
Execution of ./example1 aborted due to compilation errors.
Also, I have read somewhere in the forums about 'our' and 'my' keywords. Using these seems to work. But, is it compulsory to use these keywords. If so, I think it is strange that the book did not include them.
The issue is the 'use strict' (which is actually a very good thing).
The result is that your variables need to be declared as follows:
my $radius = <STDIN>;
The 'my' keyword, there, makes the variable local to the current scope. And the 'use strict;' says you must declare all variables and specify their scope. The two typical ways you'd want to declare variables are:
my $localOnly;
our $shareableVariable;
Basically: use 'my' when you don't want anyone else to access the variable, and use 'our' when you want to allow external code to access or set the variable.
You've already got (and accepted) a answer to this question. But it might be worth raising another couple of points.
Firstly, if you don't understand a Perl error message, then it's often worth adding use diagnostics to your code. That will give you a more detailed explanation of the error. In this case, it would say:
(F) You've said "use strict" or "use strict vars", which indicates
that all variables must either be lexically scoped (using "my" or
"state"), declared beforehand using "our", or explicitly qualified to
say which package the global variable is in (using "::").
(Which, incidentally, shows the small omissions in the previous answer.)
Secondly, are you saying that your book recommends use strict but doesn't mention my? That sounds very strange. In any case, a Perl book that doesn't mention my is not a very good Perl book. Please tell us the title so that we can avoid it.
Before writing this program,I thought that our is a package scope variable and my is
a file scope variable.But,After did that program,I am get confused.
My program is,
#!/usr/bin/perl
use strict;
use warnings;
package one;
our $val = "sat";
my $new = "hello";
print "ONE:val =>$val \n";
print "ONE:new =>$new \n\n";
package two;
print "TWO:val =>$val \n";
print "TWO:new =>$new \n";
which outputs
ONE:val =>sat
ONE:new =>hello
TWO:val =>sat
TWO:new =>hello
So,what is the difference between my and our.Whether the both are the same or it having any difference?
As you see, both my and our have lexical effect.
my creates a lexically scoped variable.
our creates a lexically scoped alias to a package variable.
Just because you say package in no fashion changes the lexical scope, so your $val is still an alias to $one::val even after having seen the package two statement.
If you don’t see a close curly, you haven’t finished your scope. (Or EOF or end of string in a string eval).
my restrict the variables access to the innermost block in which
they were declared. If there is no block, they are file-scoped.
our instead associates a
simple name with a package variable in the current package , so it is declared at the package level and linked to the package name. our tries to help out by letting you use package variables without adding the package name.
package pack;
our $variable; # These are the same
$pack::variable; # These are the same
An our variable is something similar to C's static variable, but is different because the variable declared with our in a function is still accessible outside the function if it is called with the variable's fully qualified name.
But most of all my is lexically scoped while our is lexical scope but their life persistent even outside the declaring block(their life is like global variable life), therefore to really understand the difference between my and our you have to understand the difference between lexically and global scoped in Perl.
So briefly the difference between the two type are :
Global variables
Any code, anywhere, can change their values.
Lexical variables
The life of the variable end with the the end of the code block in with they are included, after that their values are garbage collected. These kind of variables can be accessed only within the block in which they are declared.
To answer you specific example-question : try to move the second package declaration (package two) into another file, and you will see the difference between my and our ...
It is important to distinguish between visibility and lifetime.
The visibility of variables declared using our or my is identical. You can used the name anywhere after the declaration before the first enclosing brace or end of file.
Beware that this doesn't apply to full-qualified variable names, which need no declaration and can be accessed anywhere. Without declaring anything I can assign to a package variable
$pack::three = 3;
and use that anywhere else in any package. I don't even have to declare the pack package. But if I write
package pack;
our $three;
I have generated an shortened alias for $pack::three that I can use within the same lexical scope as I could a my variable in the same place: before an enclosing brace or end of file.
These package variables are always available from the start of the program's execution. Just like hash elements you can always assign to a new one and it will always be there - their lifetime is endless. In fact package variables are hash elements to all intents and purposes.
Lexical variables, declared with my, on the other hand, are created at the point of declaration and destroyed once they go out of scope and there is no reference to them held anywhere. So, unless you take the reference of such a variable, its lifetime is the same as its visibility. A my declaration inside a loop causes a new variable to be created and destroyed for each execution the loop.
In your code, you have created an alias $val for package variable $one::val and a lexical variable $new. Neither are within a code block so both are visible to the end of the file. The package two has no effect at all here, but if you had written our $val after that second package statement you would have changed the alias $val to indicate $two::val instead.
I hope that helps.
From the "our" perldoc:
our has the same scoping rules as my, but does not necessarily create a variable.
This means that variables declared with our should not be visible across files, because file is the largest lexical scope. But this is not true. Why?
You can consider our to create a lexically-scoped alias to a package global variable. Package globals are accessible from everywhere; that's what makes them global. But the name created by our is only visible within the lexical scope of the our declaration.
package A;
use strict;
{
our $var; # $var is now a legal name for $A::var
$var = 42; # LEGAL
}
say $var; # ILLEGAL: "global symbol $var requires explicit package name"
say $A::var; # LEGAL (always)
{
our $var; # This is the same $var as before, back in scope
$var *= 2; # LEGAL
say $var; # 84
}
You have a good answer already, but perhaps this will be helpful as well.
The our declaration combines aspects of my and use vars. It functions similarly to use vars in that it declares package variables; however, variables declared in this way are lexically scoped and cannot be accessed outside the scope in which they were declared (unless you use the fully qualified name of the variable). In addition, a variable declared with our is visible across its entire lexical scope, even across package boundaries.
Here's a table that I added to my Perl notes a while back. For an example, see this SO answer.
Scope/ Package
Namespace Variable Private New
---------------------------------------------------
my Lexical No Yes Yes
our Lexical Yes No No
use vars Package Yes No No