my
Perl'de ne olduğunu biliyorum . Yalnızca tanımlandığı bloğun kapsamında bulunan bir değişkeni tanımlar. Ne yapar our
?
Nasıl mu our
farklı my
?
my
Perl'de ne olduğunu biliyorum . Yalnızca tanımlandığı bloğun kapsamında bulunan bir değişkeni tanımlar. Ne yapar our
?
Nasıl mu our
farklı my
?
Yanıtlar:
Harika soru: our
Farkı my
nedir ve ne yapar our
?
Özetle:
Perl 5'ten beri mevcut olan, my
paket dışı değişkenleri bildirmenin bir yoludur, bunlar:
$package_name::variable
.Öte yandan, our
değişkenler paket değişkenleridir ve dolayısıyla otomatik olarak:
$package_name::variable
.Bir değişkeni our
tanımlamak, değişkenleri use strict
yazım hatası veya derleme zamanı hataları almadan kullanmak için önceden bildirmenizi sağlar . Perl 5.6'dan beri use vars
, sadece dosya kapsamındaki ve sözlüksel olarak kapsam dışı olan eski olanın yerini almıştır our
.
Örneğin, değişken için resmi nitelikli adı $x
içeriden package main
olduğunu $main::x
. Bildirme , komut dosyasını veya our $x
kullandığında, açık $x
değişkenini ceza olmadan (yani, sonuçta ortaya çıkan bir hata olmadan) kullanmanıza izin verir . Kapsam bir veya iki veya daha fazla paket veya bir küçük blok olabilir.use strict
use strict "vars"
local
değişken oluşturmaz. Hiçbir şekilde my
ve hiç alakalı değildir our
. local
değişkenin değerini geçici olarak yedekler ve geçerli değerini siler.
our
değişkenler paket değişkenleri değildir. Küresel kapsamda değil, aynı değişkenler gibi sözlüksel olarak kapsamlı my
değişkenler. Aşağıdaki programda görebilirsiniz: package Foo; our $x = 123; package Bar; say $x;
. Bir paket değişkenini "bildirmek" istiyorsanız, kullanmanız gerekir use vars qw( $x );
. , derlendiği our $x;
paketteki aynı adlı değişkenle diğer adla adlandırılan sözlüksel olarak kapsamlı bir değişkeni bildirir our
.
Cartman ve Olafur'dan PerlMonks ve PerlDoc bağlantıları harika bir referanstır - aşağıda bir özette benim çatlak:
my
değişkenler, s {}
içinde değilse, aynı dosya tarafından veya aynı dosya içinde tanımlanan tek bir blok içinde sözcüksel olarak kapsamlandırılır {}
. Aynı sözcüksel kapsamın / bloğun dışında tanımlanan paketlerden / altyordamlardan erişilemez.
our
değişkenler bir paket / dosya içinde kapsamlı ve herhangi bir kod erişilebilir olan use
veya require
bu paket / dosya - adı çakışmaları uygun ad alanını ekleyerek bu paketler arasında çözülür.
Yuvarlamak için, local
değişkenler "dinamik olarak" kapsamlıdır, my
değişkenlerden farklıdır, çünkü aynı blok içinde çağrılan alt rutinlerden de erişilebilirler.
my
değişkenler aynı dosya içinde {}
s olarak yer almıyorsa [...] " Bu benim için yararlı oldu, teşekkürler.
Bir örnek:
use strict;
for (1 .. 2){
# Both variables are lexically scoped to the block.
our ($o); # Belongs to 'main' package.
my ($m); # Does not belong to a package.
# The variables differ with respect to newness.
$o ++;
$m ++;
print __PACKAGE__, " >> o=$o m=$m\n"; # $m is always 1.
# The package has changed, but we still have direct,
# unqualified access to both variables, because the
# lexical scope has not changed.
package Fubb;
print __PACKAGE__, " >> o=$o m=$m\n";
}
# The our() and my() variables differ with respect to privacy.
# We can still access the variable declared with our(), provided
# that we fully qualify its name, but the variable declared
# with my() is unavailable.
print __PACKAGE__, " >> main::o=$main::o\n"; # 2
print __PACKAGE__, " >> main::m=$main::m\n"; # Undefined.
# Attempts to access the variables directly won't compile.
# print __PACKAGE__, " >> o=$o\n";
# print __PACKAGE__, " >> m=$m\n";
# Variables declared with use vars() are like those declared
# with our(): belong to a package; not private; and not new.
# However, their scoping is package-based rather than lexical.
for (1 .. 9){
use vars qw($uv);
$uv ++;
}
# Even though we are outside the lexical scope where the
# use vars() variable was declared, we have direct access
# because the package has not changed.
print __PACKAGE__, " >> uv=$uv\n";
# And we can access it from another package.
package Bubb;
print __PACKAGE__, " >> main::uv=$main::uv\n";
Kapsam Belirleme ile başa çıkmak Perl kapsam belirleme kurallarına iyi bir genel bakıştır. our
Metnin gövdesinde tartışılmayacak kadar eski . Sondaki Notlar bölümünde ele alınmaktadır .
Makale, paket değişkenleri ve dinamik kapsamdan ve bunun sözcük değişkenlerinden ve sözcüksel kapsamdan nasıl farklı olduğu hakkında konuşuyor.
my
yerel değişkenler our
için kullanılırken, global değişkenler için kullanılır.
Perl'deki Değişken Kapsam Belirleme'de daha fazla okuma : temel bilgiler .
${^Potato}
küreseldir. Nerede kullandığınızdan bağımsız olarak aynı değişkeni ifade eder.
Bu soru ile de ilgili olan, beni berbat eden Perl'deki sözlü bildirimlerle ilgili bazı tuzaklarla karşılaştım, bu yüzden sadece özetimi buraya ekliyorum:
1. Tanım veya beyan?
local $var = 42;
print "var: $var\n";
Çıktı var: 42
. Ancak local $var = 42;
, bir tanım veya bildirim olup olmadığını söyleyemedik . Ama buna ne dersiniz:
use strict;
use warnings;
local $var = 42;
print "var: $var\n";
İkinci program bir hata verecektir:
Global symbol "$var" requires explicit package name.
$var
tanımlanmamıştır, bunun anlamı local $var;
sadece bir bildiridir! local
Bir değişkeni bildirmek için kullanmadan önce değişkenin daha önce bir global değişken olarak tanımlandığından emin olun.
Ama bu neden başarısız olmaz?
use strict;
use warnings;
local $a = 42;
print "var: $a\n";
Çıktısı: var: 42
.
Yıllardan Bunun nedeni $a
, sıra sıra $b
, bir genel değişken Perl önceden tanımlanmış olduğunu. Sıralama işlevini hatırlıyor musunuz?
2. Sözcüksel mi yoksa küresel mi?
Perl kullanmaya başlamadan önce bir C programcısıydım, bu yüzden lexical ve global değişkenler kavramı benim için basit görünüyor: sadece C'deki otomatik ve harici değişkenlere karşılık geliyor. Ama küçük farklılıklar var:
C de harici değişken, herhangi bir fonksiyon bloğunun dışında tanımlanan bir değişkendir. Diğer yandan, otomatik bir değişken, fonksiyon bloğu içinde tanımlanan bir değişkendir. Bunun gibi:
int global;
int main(void) {
int local;
}
Perl'deyken, işler ince:
sub main {
$var = 42;
}
&main;
print "var: $var\n";
Çıktı var: 42
. $var
bir fonksiyon bloğunda tanımlanmış olsa bile global bir değişkendir! Aslında Perl'de herhangi bir değişken varsayılan olarak global olarak bildirilir.
Ders her zaman use strict; use warnings;
bir Perl programının başlangıcına eklemektir , bu da programcıyı sözlü değişkeni açıkça beyan etmeye zorlar, böylece verilen bazı hatalardan dolayı karışıklık yaşarız.
Perldoc kızımız biraz iyi tanımı vardır.
Hem bir değişken için depolama alanı ayıran hem de geçerli kapsamda kullanım için bu depolama ile basit bir ad ilişkilendiren my'imden farklı olarak, geçerli kapsamda kullanım için basit bir adı geçerli paketteki bir paket değişkeni ile ilişkilendirir. Başka bir deyişle, bizimki ile aynı kapsam belirleme kurallarına sahiptir, ancak mutlaka bir değişken oluşturmaz.
Bu sadece soru ile ilgili, ama ben sadece "benim" (yerel) ile kullanamazsınız "bizim" (paket) değişkenleri ile kullanabileceğiniz (bana) belirsiz bir perl sözdizimi keşfettim değişkenler.
#!/usr/bin/perl
our $foo = "BAR";
print $foo . "\n";
${"foo"} = "BAZ";
print $foo . "\n";
Çıktı:
BAR
BAZ
'Bizim' kelimemizi 'benim' olarak değiştirirseniz bu işe yaramaz.
perl -e "my $foo = 'bar'; print $foo; ${foo} = 'baz'; pr int $foo"
output: barbaz
perl -e "my $foo = 'bar'; print $foo; ${"foo"} = 'baz'; print $foo"
output: barbaz
perl -e "my $foo = 'bar'; print $foo; ${\"foo\"} = 'baz'; print $foo"
output: barbar
Bu yüzden testimde aynı tuzağa düştüm. $ {foo} $ foo ile aynıdır, parantezler enterpolasyon yaparken kullanışlıdır. $ {"foo"} aslında ana sembol tablosu olan $ main :: {} 'a bir bakıştır, çünkü sadece paket kapsamındaki değişkenleri içerir.
perl -e "package test; our $foo = 'bar'; print $foo; ${\"foo\"} = 'baz'; print $foo"
bu bağlamda $ {"foo"} artık $ {"test :: foo"} 'ya eşit çalışmalardır. Sembol Tabloları ve Küreler hakkında Gelişmiş Perl programlama kitabı gibi bazı bilgiler vardır. Önceki hatam için özür dilerim.
print "package is: " . __PACKAGE__ . "\n";
our $test = 1;
print "trying to print global var from main package: $test\n";
package Changed;
{
my $test = 10;
my $test1 = 11;
print "trying to print local vars from a closed block: $test, $test1\n";
}
&Check_global;
sub Check_global {
print "trying to print global var from a function: $test\n";
}
print "package is: " . __PACKAGE__ . "\n";
print "trying to print global var outside the func and from \"Changed\" package: $test\n";
print "trying to print local var outside the block $test1\n";
Bunu çıktılayacak:
package is: main
trying to print global var from main package: 1
trying to print local vars from a closed block: 10, 11
trying to print global var from a function: 1
package is: Changed
trying to print global var outside the func and from "Changed" package: 1
trying to print local var outside the block
Komut dosyasını çalıştırmaya çalışırken "katı kullanın" ifadesi kullanıldığında bu hatayı alırsınız:
Global symbol "$test1" requires explicit package name at ./check_global.pl line 24.
Execution of ./check_global.pl aborted due to compilation errors.
Sadece aşağıdaki programı kullanmaya çalışın:
#!/usr/local/bin/perl
use feature ':5.10';
#use warnings;
package a;
{
my $b = 100;
our $a = 10;
print "$a \n";
print "$b \n";
}
package b;
#my $b = 200;
#our $a = 20 ;
print "in package b value of my b $a::b \n";
print "in package b value of our a $a::a \n";
#!/usr/bin/perl -l
use strict;
# if string below commented out, prints 'lol' , if the string enabled, prints 'eeeeeeeee'
#my $lol = 'eeeeeeeeeee' ;
# no errors or warnings at any case, despite of 'strict'
our $lol = eval {$lol} || 'lol' ;
print $lol;
our
ve my
farklı? Bu örnek bunu nasıl gösteriyor?
Bir yorumlayıcının gerçekte ne olduğunu düşünelim: bu, değerleri bellekte saklayan bir kod parçasıdır ve bir programdaki talimatların bu değerlere, bu talimatlarda belirtilen adlarına göre erişmesine izin verir. Dolayısıyla, bir tercümanın büyük işi, tercümanın depoladığı değerlere erişmek için bu talimatlardaki isimleri nasıl kullanmamız gerektiğine dair kuralları şekillendirmektir.
"My" ile karşılaşıldığında, yorumlayıcı sözcüksel bir değişken oluşturur: yorumlayıcının yalnızca bir blok yürütürken ve yalnızca sözdizimsel bloğun içinden erişebileceği adlandırılmış bir değer. "Bizim" ile karşılaşıldığında, yorumlayıcı bir paket değişkeninin sözcüksel takma adını yapar: yorumlayıcının bundan sonra blok bitene kadar sözlük değişkeninin adı olarak işlemesi gereken bir adı paketin değerine bağlar. aynı ada sahip değişken.
Etkisi, daha sonra bir sözlük değişkeni kullandığınızı iddia edebilir ve paket değişkenlerinin tam niteliği üzerine 'katı kullanım' kurallarını atlayabilirsiniz. Yorumlayıcı ilk kullanıldıklarında otomatik olarak paket değişkenleri yarattığından, "bizim" kullanmanın yan etkisi de yorumlayıcının bir paket değişkeni oluşturması olabilir. Bu durumda, iki şey yaratılır: 'paketin sıkı kullanımı' (paketinin adı ve iki sütununun adı ile eklenir) tarafından istendiği gibi doğru bir şekilde tanımlanması koşuluyla, yorumlayıcının her yerden erişebileceği bir paket değişkeni ve sözcüksel takma .
Kaynaklar: