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 <[email protected]> -- 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 -- -------------------------------------------------------------------------package
Ada.Environment_Variablesis
pragma
Preelaborate (Environment_Variables);function
Value (Name :in
String)return
String;function
Exists (Name :in
String)return
Boolean;procedure
Set (Name :in
String; Value :in
String);procedure
Clear (Name :in
String);procedure
Clear;procedure
Iterate (Process :not
null
access
procedure
(Name :in
String; Value :in
String));end
Ada.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