12 Soru: Perl’de benim ve bizim aramızdaki fark nedir?

tarafından oluşturulan soru Fri, Jan 30, 2015 12:00 AM

my'un Perl'de ne olduğunu biliyorum. Yalnızca tanımlandığı bloğun kapsamında bulunan bir değişkeni tanımlar. our ne yapıyor? our'un my'dan farkı nedir?

    
176
12 Yanıtlar                              12                         

Harika bir soru: our my 'dan ne kadar farklıdır ve our yap?

Özetle:

5 Perl'den beri kullanılabilen my aşağıdakileri beyan etmenin bir yoludur:

  • paket dışı değişkenler, yani
  • özel,
  • yeni ,
  • global olmayan değişkenler,
  • herhangi bir paketten ayrı. Böylece değişkenine $package_name::variable biçiminde erişilemez.


Diğer yandan, our değişkenleri şunlardır:

  • paket değişkenleri ve böylece otomatik olarak
  • genel değişkenler
  • kesinlikle özel değil ,
  • ne de mutlaka yeni değillerdir; ve onlar
  • Paketin dışından erişilebilir. $package_name::variable olarak kalifiye ad alanı.


Bir değişkeni our ile bildirmek, yazım hatası uyarıları veya derleme zamanı hataları almadan bunları use strict altında kullanmak için değişkenleri önceden bildirmenize olanak sağlar . Perl 5.6’dan bu yana, yalnızca use vars kadar eski ve our yerini aldı. >

Örneğin, $x içindeki package main değişkeni için resmi ve nitelikli ad $main::x'dur. our $x 'i bildirmek, çıplak $x değişkenini, bülteninde use strict’u kullandığında, bildirimin kapsamında, ceza almadan (yani sonuçta bir hata olmadan) kullanmanızı sağlar. veya use strict "vars" . Kapsam bir veya iki veya daha fazla paket veya bir küçük blok olabilir.

    
206
2009-08-18 23: 37: 13Z
  1. Öyleyse bizim yerelden ne farkı var?
    2009-08-23 13: 51: 43Z
  2. @ Nathan Fellman, local değişken oluşturmaz. Hiç my ve our ile ilgili değil. local değişkenin değerini geçici olarak yedekler ve geçerli değerini temizler.
    2011-09-21 16: 57: 21Z
  3. our değişkenleri paket değişkenleri değil. Genel olarak kapsamlı değildirler, ancak my değişkenleri gibi sözlüksel kapsamda değişkenler. Bunu aşağıdaki programda görebilirsiniz: package Foo; our $x = 123; package Bar; say $x;. Bir paket değişkeni "bildirmek" istiyorsanız, use vars qw( $x ); kullanmanız gerekir. our $x;, our'un derlendiği paketteki aynı adlandırılmış değişkene diğer adlarla yazılmış, sözcüksel bir kapsam değişkeni bildirir.
    2016-11-20 01: 15: 26Z

cartman ve Olafur'dan PerlMonks ve PerlDoc bağlantıları harika bir referans - aşağıda özet olarak yerimden biri:

my değişkenleri {} tarafından tanımlanmış tek bir blok içinde veya {} s'de değilse aynı dosya içinde sözcüksel olarak kapsamlanır. Aynı sözcük kapsamı /bloğu dışında tanımlanan paketlerden /alt rutinlerden erişilemez.

our değişkenleri bir paket /dosya içinde yer alır ve uygun ad alanını hazırlayarak paketler arasında paket /dosya adı çakışmalarının giderildiği use veya require kodlarından erişilebilir.

Bunu düzeltmek için, local değişkenleri "dinamik olarak" kapsamlıdır, my değişkenlerinden farklı olarak aynı blok içinde adı verilen alt yordamlardan da erişilebilirler.

    
59
2013-12-06 08: 02: 30Z
  1. {} değişkenleri aynı dosya içinde sözcüksel olarak kapsam dahilinde [...] ". Bu benim için faydalı oldu, teşekkürler.
    2016-10-01 06: 41: 51Z

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";
    
48
2016-08-28 03: 24: 36Z
  1. İyi cevap. Çok yazık, birden fazla kez oylayamıyorum.
    2009-06-13 17: 52: 16Z
  2. # 5 yerine, yorumun # 2'u okuması gerekir.
    2015-11-20 18: 46: 37Z

Scoping ile Başa Çıkma Perl kapsam belirleme kurallarına genel bir bakış niteliğindedir. our'un metnin gövdesinde tartışılmadığı kadar eski. Sonunda Notlar bölümünde ele alınmaktadır.

Makale, paket değişkenleri ve dinamik kapsam ve bunun sözlüksel değişkenler ve sözcüksel kapsamdan nasıl farklı olduğu hakkında konuşuyor.

    
12
2009-05-10 16: 37: 42Z

benim yerel değişkenler için kullanılır, burada global değişkenler için kullanılır. Perl'de Değişken Kapsam: temel bilgiler hakkında daha fazla okuma.

    
6
2009-05-10 10: 27: 50Z
  1. Yerel ve global sözcükleri dolaşırken dikkatli olun. Uygun terimler sözcük ve pakettir. Perl'de gerçek global değişkenler oluşturamazsınız, ancak bazıları zaten $_ gibi var ve local, yerel değişkenlerle (yerel tarafından oluşturulan) paket değişkenleri (sözcüksel değişkenlerle (benimkiyle oluşturulmuş) oluşturuyor) ifade ediyor.
    2009-05-11 00: 16: 08Z
  2. ${^Potato} geneldir. Nerede kullandığınıza bakmaksızın aynı değişkeni ifade eder.
    2013-10-07 14: 02: 56Z

Bu eski bir soru, ancak bu soruyla da ilgili olan Perl'deki sözlü bildirilerle ilgili bazı sıkıntılarla karşılaştım, bu yüzden de özetimi buraya ekledim:

1 . tanımı veya bildirimi?

 
local $var = 42; 
print "var: $var\n"; 

Çıkış var: 42. Ancak local $var = 42;'un bir tanım mı, beyan mı olduğunu söyleyemedik. Ancak 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ımlanmadı, yani local $var; yalnızca bir bildirimdir! Bir değişkeni bildirmek için local'u kullanmadan önce, bunun daha önce global bir değişken olarak tanımlandığından emin olun.

Fakat bu neden başarısız olmayacak?

 
use strict;
use warnings;

local $a = 42;
print "var: $a\n";

Çıktı: var: 42.

Çünkü $a ve $b, Perl'de önceden tanımlanmış bir global değişkendir. sort işlevini hatırlayın?

2 . sözcüksel mi yoksa genel mi?

Perl'i kullanmaya başlamadan önce bir C programcısıydım, bu yüzden sözcüksel ve küresel değişkenler kavramı bana basit geliyor: 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ımlanmış bir değişkendir. Öte yandan, otomatik değişken, fonksiyon bloğunda tanımlanan bir değişkendir. Bunun gibi:

 
int global;

int main(void) {
    int local;
}

Perl'deyken her şey çok incedir:

 
sub main {
    $var = 42;
}

&main;

print "var: $var\n";

Çıktı var: 42, $var, bir fonksiyon bloğu içinde tanımlanmış olsa bile global bir değişkendir.ck! Aslında Perl'de, herhangi bir değişken varsayılan olarak global olarak bildirilir.

Ders, bir Perl programının başlangıcına her zaman use strict; use warnings;'u eklemektir; bu, programlayıcıyı, sözcük değişkenini açıkça bildirmeye zorlar, böylece verilen hatalardan dolayı karışıklığa uğramazız.

    
5
2013-11-07 15: 31: 02Z
  1. ["a [$a ve $b $] sıralama] burada daha fazlasını] ( stackoverflow.com/a/26128328/1028230 ). Perl asla beni şaşırtmaz, um, beni şaşırtmaz.
    2015-02-10 19: 47: 14Z

perldoc 'ın iyi bir tanımı vardır.

  

Hem değişkene depolama alanını ayırıp hem de bu kapsamla basit bir adı mevcut kapsam dahilinde kullanmakla ilişkilendiren benimkilerden farklı olarak, geçerli kapsamda kullanmak için mevcut paketteki bir paket değişkeniyle basit bir adı ilişkilendirir. Başka bir deyişle, bizim ile aynı kapsam kuralları vardır, ancak mutlaka bir değişken oluşturmaz.

    
4
2009-05-11 00: 23: 17Z

Bu sadece biraz soru ile ilgili, ancak "benim" ile kullanamayacağınız "our" (paket) değişkenleriyle kullanabileceğiniz bir (benim için) gizlenmiş bir perl sözdizimi keşfettim. (yerel) 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.

    
2
2011-12-02 15: 03: 03Z
  1. Öyle değil. $foo ${foo} ${'foo'} ${"foo"} hepsi değişken atama veya düzenleme yapma için aynı şekilde çalışır. Yukarıdaki örnekte bizim yerine benim çalışıyor. Muhtemelen deneyimlediğiniz şey, $foo'yu bir paket değişkeni olarak, $main :: foo veya $:: foo gibi bir paket değişkeni olarak düzenlemeye çalışıyordu; bu, yalnızca our ile tanımlananlar gibi paket globaller için çalışacaktı. /div>
    2014-10-21 14: 08: 33Z
  2. Sadece v5.20 kullanılarak tekrar denendi ve kesinlikle ile aynı çıktıyı vermedi (BAR'ı iki kez yazdırıyor.)
    2014-10-21 17: 50: 24Z
  3. Testim (pencerelerde): perl -e "my $foo = 'bar'; print $foo; ${foo} = 'baz'; pr int $foo" çıktı: barbaz perl -e "my $foo = 'bar'; print $foo; ${"foo"} = 'baz'; print $foo" çıktı: barbaz perl -e "my $foo = 'bar'; print $foo; ${\"foo\"} = 'baz'; print $foo" çıktı: 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 :: {} 'e bakar, çünkü sadece paket kapsamlı değişkenleri içerir.
    2014-11-22 13: 44: 28Z
  4. ${"main :: foo"}, ${":: foo"} ve $main :: foo, ${"foo"} ile aynıdır. . Kısayol perl -e "package test; our $foo = 'bar'; print $foo; ${\"foo\"} = 'baz'; print $foo" paketine duyarlıdır, bu bağlamda olduğu gibi ${"foo"} şimdi ${"test :: foo"} 'e eşittir. Gelişmiş Perl programlama kitabı gibi, Sembol Tabloları ve Globlar hakkında bazı bilgiler vardır. Önceki hatam için üzgünüm.
    2014-11-22 13: 57: 56Z
 
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 Çıkaracak:

 
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 

"use strict" kullanmak durumunda, betiği çalıştırmaya çalışırken 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.
    
0
2014-09-05 20: 32: 42Z
  1. Lütfen bir tür eski durum sağlayınPlanation. Bunun gibi boşaltma kodunun nadiren uygun olduğu kabul edilir.
    2014-09-05 12: 29: 21Z
  2. basit kelimelerle: Bizim (sais ismi olarak), bu değişkeni betiğin herhangi bir yerinden (fonksiyon, blok vb ...) kullanmak için değişken bir açıklamadır, varsayılan olarak her değişken (bildirilmemesi durumunda) "ana" pakete aittir, değişkenimiz hala komut dosyasında başka bir paketin bildirilmesinden sonra bile kullanılabilir. Bir blok veya fonksiyonda belirtilen durumda "my" değişkeni, sadece bu blok /fonksiyonda kullanılabilir. "my" değişkeninin bir blokta kapatılmadığı bildirilirse, scriot'ta, kapalı bir blokta veya "our" değişkeni olarak bir fonksiyonda kullanılabilir, ancak paketin değişmesi durumunda kullanılamaz. /div>
    2014-09-06 20: 08: 46Z
  3. Yukarıdaki betiğim, varsayılan olarak "ana" pakette olduğumuzu, ardından komut dosyasının "main" paketinden "our" değişkenini (kapalı değil) yazdırdığını gösteriyor blok), o zaman bir işlevde iki "my" değişkenini bildiririz ve onları bu işlevden yazdırırız. sonra bir fonksiyonda kullanılabileceğini göstermek için başka bir fonksiyondan bir "our" değişkenini basarız. daha sonra paketi "değiştirildi" olarak değiştirdik ("ana" değil, artık değil) ve tekrar "bizim" değişkenini başarıyla yazdırıyoruz. daha sonra işlev dışında bir "my" değişkeni yazdırmaya çalışıyor ve başarısız oldu. komut dosyası "bizim" ve "benim" kullanımım arasındaki farkı gösteriyor.
    2014-09-06 20: 13: 04Z

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";
    
0
2015-11-05 11: 08: 47Z
  1. evet, ama neden bu?
    2015-11-05 13: 11: 22Z
  2. Bu benim ve bizim arasındaki farkı açıklıyor. Değişkenim küme parantezinin dışında kapsam dışına çıkıyor ve çöp toplanıyor, ancak değişkenimiz hala yaşıyor.
    2015-11-05 14: 03: 18Z
 
#!/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;
    
- 1
2013-05-16 08: 02: 24Z
  1. Bu kodun ne anlama geldiğini açıklayabilir misiniz? our ve my neden farklı? Bu örnek nasıl gösteriyor?
    2013-05-16 11: 07: 56Z

Bir tercümanın gerçekte ne olduğunu düşünelim: bu, değerleri bellekte saklayan bir kod parçasıdır ve yorumladığı bir programdaki talimatların, bu talimatların içinde belirtilen adlarına göre bu değerlere erişmesini sağlar. Bu nedenle, bir tercümanın en büyük işi, tercümanın depoladığı değerlere erişmek için bu talimatlardaki adları nasıl kullanmamız gerektiği konusundaki kuralları belirlemektir.

"my" ile karşılaştığınızda, 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 blok içinden erişebildiği adlandırılmış bir değer. "Bizim" ifadesiyle karşılaştığımızda, yorumlayıcı bir paket değişkeninin sözcüksel bir takma ismini yapar: yorumlayıcının bundan sonra bir sözcük değişkeni adı olarak işlenmesi gereken blok ismini paketin değerine bağlar. aynı ada sahip değişken.

Etkisi, sözcüksel bir değişken kullanıyormuş gibi davranabilir ve paket değişkenlerinin tam niteliği için 'use strict' kurallarını atlayabilirsiniz. Tercüman ilk kullanıldığı zaman otomatik olarak paket değişkenleri oluşturduğundan, "our" kullanımının yan etkisi tercümanın da bir paket değişkeni yaratması olabilir. Bu durumda, iki şey yaratılır: tercümanın her yerden erişebileceği bir paket değişkeni;t 'use strict' (paketinin adı ve iki virgül ile hazırlanmıştır), ve sözcüksel takma adıyla belirtildiği şekilde istendiği şekilde uygun şekilde belirtilmiştir.

Kaynaklar:

- 1
2016-01-27 04: 57: 43Z
kaynak yerleştirildi İşte