myPerl'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 ourfarklı my?
myPerl'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 ourfarklı my?
Yanıtlar:
Harika soru: ourFarkı mynedir ve ne yapar our?
Özetle:
Perl 5'ten beri mevcut olan, mypaket dışı değişkenleri bildirmenin bir yoludur, bunlar:
$package_name::variable.Öte yandan, ourdeğişkenler paket değişkenleridir ve dolayısıyla otomatik olarak:
$package_name::variable.Bir değişkeni ourtanımlamak, değişkenleri use strictyazı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ı $xiçeriden package mainolduğunu $main::x. Bildirme , komut dosyasını veya our $xkullandığında, açık $xdeğ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 strictuse strict "vars"
localdeğişken oluşturmaz. Hiçbir şekilde myve hiç alakalı değildir our. localdeğişkenin değerini geçici olarak yedekler ve geçerli değerini siler.
ourdeğişkenler paket değişkenleri değildir. Küresel kapsamda değil, aynı değişkenler gibi sözlüksel olarak kapsamlı mydeğ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:
mydeğ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.
ourdeğişkenler bir paket / dosya içinde kapsamlı ve herhangi bir kod erişilebilir olan useveya requirebu paket / dosya - adı çakışmaları uygun ad alanını ekleyerek bu paketler arasında çözülür.
Yuvarlamak için, localdeğişkenler "dinamik olarak" kapsamlıdır, mydeğişkenlerden farklıdır, çünkü aynı blok içinde çağrılan alt rutinlerden de erişilebilirler.
mydeğ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. ourMetnin 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.
myyerel değişkenler ouriç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.
$vartanımlanmamıştır, bunun anlamı local $var;sadece bir bildiridir! localBir 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. $varbir 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;
ourve myfarklı? 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: