Ada 程式設計/庫/Ada.Environment 變數
此語言功能僅從 Ada 2005 開始提供。
Ada.Environment_Variables 是自 Ada 2005 以來 預定義語言環境 的一個單元。
The Ada.Environment_Variables 包允許 Ada 程式讀取、寫入和修改 環境變數。究竟什麼是環境變數是實現定義的。本文中的所有程式碼都編譯並在 Slackware Linux 系統上執行。使用的編譯器是 GNATMAKE GPL 2008 (20080521)。
環境變數是簡單的鍵值對。鍵和值都是字串。使用 Environment_Variables 包,我們可以檢查鍵是否存在,我們可以設定新的鍵值對,我們可以刪除鍵,我們可以讀取值,並且我們可以遍歷所有鍵值對(正如該包非常直接的規範所顯示的那樣)。
package Ada.Environment_Variables is
pragma Preelaborate (Environment_Variables);
function Value (Name : String) return String;
function Exists (Name : String) return Boolean;
procedure Set (Name : String; Value : String);
procedure Clear (Name : String);
procedure Clear;
procedure Iterate (Process : not null access procedure (Name, Value : String));
end Ada.Environment_Variables;
以下所有示例都將圍繞這個簡單的核心程式構建
with Ada.Text_IO;
with Ada.Environment_Variables;
procedure Env is
package IO renames Ada.Text_IO;
package EV renames Ada.Environment_Variables;
begin
IO.Put_Line (Item => "Environment_Variables test");
end Env;
只需在 IO.Put_Line 行之後插入以下示例中的程式碼。因此,讓我們繼續並看看如何使用 Ada 讀取環境值。
Value 的規範如下所示
function Value (Name : String) return String;
讀取環境變數是使用 Value 函式完成的。它將一個字串作為其唯一引數並返回匹配環境變數的值。嘗試將其新增到核心程式中
IO.Put_Line (Item => EV.Value (Name => "VISUAL"));
IO.Put_Line (Item => EV.Value (Name => "NONEXISTENT"));
exception
when Constraint_Error =>
IO.Put_Line (Item => "No such environment variable.");
在我的機器上執行此程式碼時,我得到以下輸出
Environment_Variables test /usr/local/bin:/usr/bin:/bin:/usr/games:/usr/lib/java/bin:/usr/lib/java/jre/bin:/usr/lib/qt/bin:.:/usr/local/texlive/2008/bin/i386-linux/ No such environment variable.
如您所見,如果給定的 Name 引數與任何現有環境變數不匹配,則會引發 Constraint_Error。如果目標作業系統不支援環境變數的概念,則會引發 Program_Error。
Ada.Environment_Variables.Value 示例原始碼
with Ada.Text_IO;
with Ada.Environment_Variables;
procedure Env is
package IO renames Ada.Text_IO;
package EV renames Ada.Environment_Variables;
begin
IO.Put_Line (Item => "Environment_Variables test");
IO.Put_Line (Item => EV.Value (Name => "PATH"));
IO.Put_Line (Item => EV.Value (Name => "NONEXISTENT"));
exception
when Constraint_Error =>
IO.Put_Line (Item => "No such environment variable.");
end Env;
Exists 的規範如下所示
function Exists (Name : String) return Boolean;
Exists 函式用於檢查給定環境變數名稱是否為作業系統所知。如果是,則該函式將返回布林值 True,否則返回布林值 False。
if EV.Exists (Name => "PATH") then
IO.Put_Line (Item => "EXISTS!");
else
IO.Put_Line (Item => "DOES NOT EXIST!");
end if;
if EV.Exists (Name => "NONEXISTENT") then
IO.Put_Line (Item => "EXISTS!");
else
IO.Put_Line (Item => "DOES NOT EXIST!");
end if;
在我的計算機上產生的結果輸出為
Environment_Variables test EXISTS! DOES NOT EXIST!
手冊中沒有說明在這種情況下執行環境缺乏對環境變數支援時會發生什麼,但我懷疑會引發 Program_Error,就像 Value 一樣。
Ada.Environment_Variables.Exists 示例原始碼
with Ada.Text_IO;
with Ada.Environment_Variables;
procedure Env is
package IO renames Ada.Text_IO;
package EV renames Ada.Environment_Variables;
begin
IO.Put_Line (Item => "Environment_Variables test");
if EV.Exists (Name => "PATH") then
IO.Put_Line (Item => "EXISTS!");
else
IO.Put_Line (Item => "DOES NOT EXIST!");
end if;
if EV.Exists (Name => "NONEXISTENT") then
IO.Put_Line (Item => "EXISTS!");
else
IO.Put_Line (Item => "DOES NOT EXIST!");
end if;
end Env;
Set 的規範如下所示
procedure Set (Name : String; Value : String);
使用 Set,我們可以定義新的環境變數和更改現有環境變數
if not EV.Exists (Name => "NONEXISTENT") then
IO.Put_Line (Item => "DOES NOT EXIST!");
end if;
EV.Set (Name => "NONEXISTENT",
Value => "FooBar");
IO.Put_Line (Item => EV.Value (Name => "NONEXISTENT"));
EV.Set (Name => "NONEXISTENT",
Value => "FooBar again");
IO.Put_Line (Item => EV.Value (Name => "NONEXISTENT"));
此程式碼的輸出為
Environment_Variables test DOES NOT EXIST! FooBar FooBar again
如果作業系統環境禁止設定或更改給定的環境變數,則會引發 Constraint_Error。與 Value 一樣,如果執行環境沒有環境變數的概念,則會引發 Program_Error。
Ada.Environment_Variables.Set 示例原始碼
with Ada.Text_IO;
with Ada.Environment_Variables;
procedure Env is
package IO renames Ada.Text_IO;
package EV renames Ada.Environment_Variables;
begin
IO.Put_Line (Item => "Environment_Variables test");
if not EV.Exists (Name => "NONEXISTANT") then
IO.Put_Line (Item => "DOES NOT EXIST!");
end if;
EV.Set (Name => "NONEXISTANT",
Value => "FooBar");
IO.Put_Line (Item => EV.Value (Name => "NONEXISTENT"));
EV.Set (Name => "NONEXISTANT",
Value => "FooBar again");
IO.Put_Line (Item => EV.Value (Name => "NONEXISTENT"));
end Env;
Clear 的規範如下所示
procedure Clear (Name : String);
procedure Clear;
刪除環境變數是使用 Clear 過程之一完成的。如果給出了 Name 引數,則 Clear 將嘗試刪除所有具有該名稱的環境變數。如果沒有給出 Name 引數,Clear 將嘗試刪除所有現有的環境變數。
首先讓我們看看 Clear 在給出 Name 引數時的工作方式
EV.Set (Name => "Foo",
Value => "This is Foo");
IO.Put_Line (Item => EV.Value (Name => "Foo"));
EV.Clear (Name => "Foo");
IO.Put_Line (Item => EV.Value (Name => "Foo"));
exception
when Constraint_Error =>
IO.Put_Line (Item => "Environment variable Foo does not exist");
以及輸出
Environment_Variables test This is Foo Environment variable Foo does not exist
現在讓我們看看 Clear 在沒有 Name 引數的情況下如何執行
EV.Set (Name => "Foo",
Value => "This is Foo");
IO.Put_Line (Item => EV.Value (Name => "Foo"));
EV.Set (Name => "Bar",
Value => "This is Bar");
IO.Put_Line (Item => EV.Value (Name => "Bar"));
EV.Clear;
if not EV.Exists (Name => "Foo") and not EV.Exists (Name => "Bar") then
IO.Put_Line (Item => "Foo and Bar are both gone!");
end if;
輸出為
Environment_Variables test This is Foo This is Bar Foo and Bar are both gone!
完全符合預期。
Ada.Environment_Variables.Clear 示例原始碼
with Ada.Text_IO;
with Ada.Environment_Variables;
procedure Env is
package IO renames Ada.Text_IO;
package EV renames Ada.Environment_Variables;
begin
IO.Put_Line (Item => "Environment_Variables test");
EV.Set (Name => "Foo",
Value => "This is Foo");
IO.Put_Line (Item => EV.Value (Name => "Foo"));
EV.Clear (Name => "Foo");
IO.Put_Line (Item => EV.Value (Name => "Foo"));
exception
when Constraint_Error =>
IO.Put_Line (Item => "Environment variable Foo does not exist");
end Env;
with Ada.Text_IO;
with Ada.Environment_Variables;
procedure Env is
package IO renames Ada.Text_IO;
package EV renames Ada.Environment_Variables;
begin
IO.Put_Line (Item => "Environment_Variables test");
EV.Set (Name => "Foo",
Value => "This is Foo");
IO.Put_Line (Item => EV.Value (Name => "Foo"));
EV.Set (Name => "Bar",
Value => "This is Bar");
IO.Put_Line (Item => EV.Value (Name => "Bar"));
EV.Clear;
if not EV.Exists (Name => "Foo") and not EV.Exists (Name => "Bar") then
IO.Put_Line (Item => "Foo and Bar are both gone!");
end if;
end Env;
Iterate 的規範如下所示
procedure Iterate (Process : not null access procedure (Name, Value : String));
Iterate 使我們能夠依次處理在執行時可用於程式的所有環境變數。我們可以透過建立一個接受兩個 String 引數的過程,然後讓 Iterate 訪問此過程來做到這一點。
這樣的程式可能看起來像這樣
with Ada.Text_IO;
with Ada.Environment_Variables;
procedure Env is
package IO renames Ada.Text_IO;
package EV renames Ada.Environment_Variables;
procedure Print_EV (Name, Value : in String) is
begin
IO.Put_Line (Item => Name & "=" & Value);
end Print_EV;
begin
IO.Put_Line (Item => "Environment_Variables test");
EV.Iterate (Process => Print_EV'Access);
end Env;
以下是上述程式在我的系統上生成的輸出的小樣本
JAVA_HOME=/usr/lib/java HOME=/home/thomas SHELL=/bin/bash
手冊中有一條關於 Iterate 的非常重要的說明。它指出
與對 Environment_Variables 包的任何子程式或 Iterate 的任何例項化進行呼叫同時呼叫 Set 或 Clear 過程會導致錯誤執行。在與 Iterate 的 Process 引數相對應的實際子程式中呼叫 Set 或 Clear 過程會導致錯誤執行。
因此,您不能在使用 Iterate 時呼叫 Set 或 Clear,至少不能在不冒一定程度的未定義行為的風險的情況下。
Ada.Environment_Variables.Iterate 示例原始碼
with Ada.Text_IO;
with Ada.Environment_Variables;
procedure Env is
package IO renames Ada.Text_IO;
package EV renames Ada.Environment_Variables;
procedure Print_EV (Name, Value : in String) is
begin
IO.Put_Line (Item => Name & "=" & Value);
end Print_EV;
begin
IO.Put_Line (Item => "Environment_Variables test");
EV.Iterate (Process => Print_EV'Access);
end Env;
-- Standard Ada library specification -- Copyright (c) 2003-2018 Maxim Reznik <reznikmm@gmail.com> -- Copyright (c) 2004-2016 AXE Consultants -- Copyright (c) 2004, 2005, 2006 Ada-Europe -- Copyright (c) 2000 The MITRE Corporation, Inc. -- Copyright (c) 1992, 1993, 1994, 1995 Intermetrics, Inc. -- SPDX-License-Identifier: BSD-3-Clause and LicenseRef-AdaReferenceManual -- -------------------------------------------------------------------------packageAda.Environment_VariablesispragmaPreelaborate (Environment_Variables);functionValue (Name :inString)returnString;functionExists (Name :inString)returnBoolean;procedureSet (Name :inString; Value :inString);procedureClear (Name :inString);procedureClear;procedureIterate (Process :notnullaccessprocedure(Name :inString; Value :inString));endAda.Environment_Variables;
外部示例
[編輯原始碼]- 在以下位置搜尋
Ada.Environment_Variables的示例:Rosetta 程式碼、GitHub (gists)、任何 Alire 包 或 本華夏公益教科書。 - 在以下位置搜尋與
Ada.Environment_Variables相關的帖子:Stack Overflow、comp.lang.ada 或 任何與 Ada 相關的頁面。
FSF GNAT
- 規範:a-envvar.ads
- 主體:a-envvar.adb
drake
