Dengan pelingkupan dinamis, callee dapat mengakses variabel peneleponnya. Kode Pseudo C:
void foo()
{
print(x);
}
void bar()
{
int x = 42;
foo();
}
Karena saya belum pernah memprogram dalam bahasa yang mendukung pelingkupan dinamis, saya ingin tahu seperti apa beberapa kasus penggunaan dunia nyata untuk pelingkupan dinamis nantinya.
Jawaban:
Aplikasi yang sangat berguna untuk pelingkupan dinamis adalah untuk melewatkan parameter kontekstual tanpa harus menambahkan parameter baru secara eksplisit ke setiap fungsi dalam tumpukan panggilan
Misalnya, Clojure mendukung pelingkupan dinamis melalui penjilidan , yang dapat digunakan untuk menetapkan kembali sementara nilai
*out*
untuk pencetakan. Jika Anda mengikat kembali*out*
maka setiap panggilan untuk mencetak dalam lingkup dinamis dari penjilidan akan mencetak ke aliran output baru Anda. Sangat berguna jika, misalnya, Anda ingin mengalihkan semua hasil cetak ke beberapa jenis log debugging.Contoh: dalam kode di bawah ini, fungsi do-stuff akan mencetak ke output debug daripada standar keluar, tetapi perhatikan bahwa saya tidak perlu menambahkan parameter output untuk melakukan-hal untuk mengaktifkan ini ....
Perhatikan bahwa binding Clojure juga bersifat lokal, jadi Anda tidak memiliki masalah dengan penggunaan bersamaan dari kemampuan ini. Ini membuat binding jauh lebih aman daripada (ab) menggunakan variabel global untuk tujuan yang sama.
sumber
(Penafian: Saya tidak pernah memprogram dalam bahasa pelingkupan dinamis)
Pelingkupan jauh lebih mudah diimplementasikan dan berpotensi lebih cepat. Dengan pelingkupan dinamis, hanya satu tabel simbol yang diperlukan (variabel saat ini tersedia). Itu hanya membaca dari tabel simbol ini untuk semuanya.
Bayangkan dalam Python fungsi yang sama.
Ketika saya memanggil bilah, saya memasukkan x ke tabel simbol. Ketika saya menelepon foo, saya mengambil tabel simbol yang saat ini digunakan untuk bar dan mendorongnya ke tumpukan. Saya kemudian memanggil foo, yang telah x diteruskan ke sana (kemungkinan telah dimasukkan ke dalam tabel simbol baru pada pemanggilan fungsi). Setelah keluar dari fungsi, saya harus menghancurkan ruang lingkup baru dan mengembalikan yang lama.
Dengan pelingkupan dinamis, ini tidak diperlukan. Saya hanya perlu mengetahui instruksi yang saya perlukan untuk kembali ketika fungsi berakhir karena tidak ada yang harus dilakukan ke tabel simbol.
sumber
Penanganan pengecualian di sebagian besar bahasa menggunakan pelingkupan dinamis; ketika pengecualian terjadi kontrol akan ditransfer kembali ke penangan terdekat pada tumpukan aktivasi (dinamis).
sumber
return
pernyataan dalam kebanyakan bahasa menggunakan pelingkupan dinamis, karena mereka mengembalikan kontrol ke penelepon di tumpukan?Tidak 100% yakin jika ini adalah pasangan yang tepat, tapi saya pikir setidaknya sudah cukup dekat dalam arti umum untuk menunjukkan di mana itu mungkin berguna untuk melanggar atau mengubah aturan pelingkupan.
Bahasa Ruby datang dengan ERB templating class, yang misalnya dalam Rails digunakan untuk menghasilkan file html. Jika Anda menggunakannya terlihat seperti ini:
The
binding
tangan akses ke variabel lokal ke ERB pemanggilan metode, sehingga dapat mengaksesnya dan menggunakannya untuk mengisi template. (Kode antara EOF adalah string, bagian antara <% =%> dievaluasi sebagai kode Ruby oleh ERB dan akan menyatakan ruang lingkupnya sendiri seperti fungsi)Contoh Rails lebih baik menunjukkan hal ini. Di pengontrol artikel, Anda akan menemukan sesuatu seperti ini:
File index.html.erb kemudian dapat menggunakan variabel lokal
@articles
seperti ini (dalam hal ini pembuatan objek ERB dan pengikatan ditangani oleh kerangka Rails, jadi Anda tidak melihatnya di sini):Jadi dengan menggunakan variabel yang mengikat, Ruby memungkinkan untuk menjalankan satu dan kode templat yang sama dalam konteks yang berbeda.
Kelas ERB hanya satu contoh penggunaan. Ruby memungkinkan secara umum untuk mendapatkan status eksekusi aktual dengan pengikatan variabel dan metode dengan menggunakan pengikatan Kernel #, yang sangat berguna dalam konteks apa pun di mana Anda ingin mengevaluasi suatu metode dalam konteks yang berbeda atau ingin menyimpan konteks untuk penggunaan nanti.
sumber
Kasus penggunaan untuk pelingkupan dinamis adalah IHMO sama dengan variabel global. Pelingkupan dinamis menghindari beberapa masalah dengan variabel global yang memungkinkan pembaruan variabel yang lebih terkontrol.
Beberapa menggunakan case yang dapat saya pikirkan:
Tentu saja pelingkupan dinamis tidak "mutlak diperlukan" tetapi meringankan beban karena harus meneruskan data gelandangan di sepanjang rantai panggilan atau harus menerapkan proksi global pintar dan manajer konteks.
Tetapi sekali lagi, pelingkupan dinamis berguna ketika berhadapan dengan jenis elemen yang sering kali diperlakukan sebagai global (logging, output, alokasi / manajemen sumber daya, dll).
sumber
Ada cukup banyak tidak ada. Saya harap Anda, misalnya, tidak pernah menggunakan variabel yang sama dua kali.
Sekarang bagaimana Anda memanggil foo dan bar dari fungsi yang sama?
Ini secara efektif mirip dengan hanya menggunakan variabel global, dan itu buruk untuk semua alasan yang sama.
sumber
x = 42; foo(); x = '42'; bar();
?