Saya tahu apa yang my
ada di Perl. Ini mendefinisikan variabel yang hanya ada dalam lingkup blok di mana ia didefinisikan. Apa yang our
harus dilakukan
Bagaimana our
berbeda dari my
?
Pertanyaan besar: Bagaimana our
berbeda dari my
dan apa yang our
lakukan?
Singkatnya:
Tersedia sejak Perl 5, my
adalah cara untuk mendeklarasikan variabel non-paket, yaitu:
$package_name::variable
.Di sisi lain, our
variabel adalah variabel paket, dan dengan demikian secara otomatis:
$package_name::variable
.Mendeklarasikan variabel dengan our
memungkinkan Anda untuk mendeklarasikan variabel untuk menggunakannya di bawah use strict
tanpa mendapat peringatan kesalahan ketik atau kesalahan waktu kompilasi. Sejak Perl 5.6, ia telah menggantikan yang sudah usang use vars
, yang hanya mencakup file, dan tidak dibatasi secara leksikal sepertiour
.
Misalnya, nama formal dan berkualitas untuk variabel $x
di dalamnya package main
adalah $main::x
. Deklarasi our $x
memungkinkan Anda untuk menggunakan $x
variabel kosong tanpa penalti (yaitu, tanpa kesalahan yang dihasilkan), dalam lingkup deklarasi, ketika skrip menggunakan use strict
atau use strict "vars"
. Lingkupnya mungkin satu, atau dua, atau lebih paket, atau satu blok kecil.
local
tidak membuat variabel. Itu tidak berhubungan denganmy
danour
sama sekali.local
sementara mencadangkan nilai variabel dan menghapus nilai saat ini.our
variabel bukan variabel paket. Mereka bukan lingkup global, tetapi variabel cakupannya leksikal sepertimy
variabel. Anda dapat melihat bahwa dalam program berikut:package Foo; our $x = 123; package Bar; say $x;
. Jika Anda ingin "mendeklarasikan" variabel paket, Anda perlu menggunakannyause vars qw( $x );
.our $x;
mendeklarasikan variabel cakupan-leksikal yang alias ke variabel dengan nama yang sama dalam paket di manaour
dikompilasi.Tautan PerlMonks dan PerlDoc dari cartman dan Olafur adalah referensi yang bagus - di bawah ini adalah ringkasan saya di ringkasan:
my
variabel dibatasi secara leksikal dalam satu blok yang ditentukan oleh{}
atau di dalam file yang sama jika tidak dalam{}
s. Mereka tidak dapat diakses dari paket / subrutin yang didefinisikan di luar lingkup / blok leksikal yang sama.our
variabel dicakup dalam suatu paket / file dan dapat diakses dari kode apa punuse
ataurequire
bahwa paket / file - konflik nama diselesaikan di antara paket dengan menambahkan ruang nama yang sesuai.Untuk mengatasinya,
local
variabel dibatasi secara "dinamis", berbeda denganmy
variabel yang juga dapat diakses dari subrutin yang disebut dalam blok yang sama.sumber
my
variabel dicakup secara leksikal [...] dalam file yang sama jika tidak dalam{}
s". Itu berguna bagi saya, terima kasih.Sebuah contoh:
sumber
Mengatasi Pelingkupan adalah gambaran umum yang baik dari aturan pelingkupan Perl. Sudah cukup tua yang
our
tidak dibahas dalam isi teks. Itu dibahas di bagian Catatan di bagian akhir.Artikel ini berbicara tentang variabel paket dan ruang lingkup dinamis dan bagaimana hal itu berbeda dari variabel leksikal dan ruang lingkup leksikal.
sumber
my
digunakan untuk variabel lokal, sedangkanour
digunakan untuk variabel global.Lebih banyak membaca di Variabel Pelingkupan di Perl: dasar-dasarnya .
sumber
${^Potato}
bersifat global. Ini merujuk ke variabel yang sama di mana pun Anda menggunakannya.Saya pernah bertemu beberapa jebakan tentang deklarasi leksikal di Perl yang mengacaukan saya, yang juga terkait dengan pertanyaan ini, jadi saya tambahkan saja ringkasan saya di sini:
1. Definisi atau deklarasi?
Outputnya adalah
var: 42
. Namun kami tidak tahu apakahlocal $var = 42;
itu definisi atau deklarasi. Tapi bagaimana dengan ini:Program kedua akan menimbulkan kesalahan:
$var
tidak didefinisikan, yang berartilocal $var;
hanya deklarasi! Sebelum menggunakanlocal
untuk mendeklarasikan variabel, pastikan bahwa itu didefinisikan sebagai variabel global sebelumnya.Tetapi mengapa ini tidak akan gagal?
Outputnya adalah:
var: 42
.Itu karena
$a
, juga$b
, adalah variabel global yang telah ditentukan sebelumnya di Perl. Ingat fungsi sortir ?2. Leksikal atau global?
Saya adalah seorang programmer C sebelum mulai menggunakan Perl, jadi konsep variabel leksikal dan global tampaknya langsung bagi saya: itu hanya sesuai dengan variabel otomatis dan eksternal dalam C. Tapi ada perbedaan kecil:
Dalam C, variabel eksternal adalah variabel yang didefinisikan di luar blok fungsi apa pun. Di sisi lain, variabel otomatis adalah variabel yang didefinisikan di dalam blok fungsi. Seperti ini:
Sementara di Perl, semuanya halus:
Outputnya adalah
var: 42
.$var
adalah variabel global bahkan jika itu didefinisikan dalam blok fungsi! Sebenarnya di Perl, variabel apa pun dinyatakan sebagai global secara default.Pelajarannya adalah untuk selalu menambahkan
use strict; use warnings;
di awal program Perl, yang akan memaksa programmer untuk mendeklarasikan variabel leksikal secara eksplisit, sehingga kita tidak menjadi kacau oleh beberapa kesalahan yang diterima begitu saja.sumber
The perldoc memiliki definisi yang baik dari kami.
sumber
Ini hanya agak terkait dengan pertanyaan, tetapi saya baru saja menemukan sedikit sintaks perl (bagi saya) yang tidak jelas yang dapat Anda gunakan dengan variabel "kami" (paket) yang tidak dapat Anda gunakan dengan "saya" (lokal) variabel.
Keluaran:
Ini tidak akan berhasil jika Anda mengubah 'kami' menjadi 'saya'.
sumber
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
Jadi dalam pengujian saya, saya jatuh ke dalam perangkap yang sama. $ {foo} sama dengan $ foo, tanda kurung berguna saat interpolasi. $ {"foo"} sebenarnya adalah tampilan hingga $ main :: {} yang merupakan tabel simbol utama, karena hanya berisi variabel scoped paket.perl -e "package test; our $foo = 'bar'; print $foo; ${\"foo\"} = 'baz'; print $foo"
, karena dalam konteks ini $ {"foo"} sekarang sama dengan $ {"test :: foo"}. Tabel Simbol dan Glob memiliki beberapa informasi tentang itu, seperti halnya buku pemrograman Advanced Perl. Maaf atas kesalahan saya sebelumnya.Akan Keluarkan ini:
Jika menggunakan "gunakan ketat" akan mendapatkan kegagalan ini saat mencoba menjalankan skrip:
sumber
Coba gunakan program berikut:
sumber
sumber
our
danmy
berbeda? Bagaimana contoh ini menunjukkannya?Mari kita pikirkan apa sebenarnya juru bahasa: itu adalah sepotong kode yang menyimpan nilai dalam memori dan membiarkan instruksi dalam program yang diinterpretasikan mengakses nilai-nilai tersebut dengan nama mereka, yang ditentukan di dalam instruksi ini. Jadi, pekerjaan besar seorang juru bahasa adalah untuk membentuk aturan bagaimana kita harus menggunakan nama-nama dalam instruksi tersebut untuk mengakses nilai-nilai yang disimpan oleh juru bahasa tersebut.
Saat menemukan "saya", interpreter menciptakan variabel leksikal: nilai bernama yang hanya dapat diakses oleh interpreter ketika mengeksekusi blok, dan hanya dari dalam blok sintaksis itu. Pada pertemuan "kita", penerjemah membuat alias leksikal dari variabel paket: ia mengikat nama, yang oleh penerjemah diharapkan sejak saat itu untuk diproses sebagai nama variabel leksikal, sampai blok selesai, dengan nilai paket variabel dengan nama yang sama.
Efeknya adalah bahwa Anda kemudian dapat berpura-pura bahwa Anda menggunakan variabel leksikal dan mengabaikan aturan 'gunakan ketat' pada kualifikasi penuh variabel paket. Karena penerjemah secara otomatis membuat variabel paket ketika mereka pertama kali digunakan, efek samping dari menggunakan "kami" juga mungkin bahwa penerjemah menciptakan variabel paket juga. Dalam hal ini, dua hal dibuat: variabel paket, yang dapat diakses oleh penerjemah dari mana-mana, asalkan ditunjuk dengan tepat seperti yang diminta oleh 'use strict' (diawali dengan nama paketnya dan dua titik dua), dan alias leksikalnya.
Sumber:
sumber