Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Environment variables

9 views
Skip to first unread message

Rafael Garcia-Suarez

unread,
Feb 22, 2005, 5:54:26 AM2/22/05
to perl6-c...@perl.org
I had this silly idea, to try to add %ENV to pugs. That would be an
interesting exercise. So I can write CGI scripts. Maybe. But I don't
know what's the Right way to do it in Perl 6. Any hints ?

--
#!/usr/bin/pugs
say "Just another Pugs hacker";

Autrijus Tang

unread,
Feb 22, 2005, 7:44:29 AM2/22/05
to Patrick R. Michaud, Autrijus Tang, Rafael Garcia-Suarez, perl6-c...@perl.org
On Tue, Feb 22, 2005 at 06:51:24AM -0600, Patrick R. Michaud wrote:
> This might initially work for read-only access/testing, but in
> the long run I suspect that %*ENV will be tied directly to the
> C putenv/getenv calls or their Parrot/other equivalents.
> Assigning to %*ENV should change the environment for any scripts
> invoked from Perl 6.

Right, I was just saying that to rgs on #perl6. :)

> (This also eliminates the runtime overhead of "populating %*ENV"
> when it's not going to be used by a particular script.)

Yup. This may very well be our first example of an IType.

Thanks,
/Autrijus/

Autrijus Tang

unread,
Feb 22, 2005, 7:35:49 AM2/22/05
to Rafael Garcia-Suarez, perl6-c...@perl.org
jn Tue, Feb 22, 2005 at 10:54:26AM -0000, Rafael Garcia-Suarez wrote:
> I had this silly idea, to try to add %ENV to pugs. That would be an
> interesting exercise. So I can write CGI scripts. Maybe. But I don't
> know what's the Right way to do it in Perl 6. Any hints ?

In Perl6 I think you do it by populating the %*ENV hash, when the
script is first run. To add it, hack Main.hs line 102 to add a new
SGlobal symbol of a VHash. If you already have a list of pairs "x",
it is as simple as:

VHash $ MkHash (listToFM x)

Now, to obtain the list of ENV, hack Posix.hs to add an import of
System.Posix.Env, and you'll have a that list of pairs via the
"getEnvironment" call:

x <- getEnvironment

Find me on #perl6 if you're unsure how to approach this. :)

Thanks,
/Autrijus/

Patrick R. Michaud

unread,
Feb 22, 2005, 7:51:24 AM2/22/05
to Autrijus Tang, Rafael Garcia-Suarez, perl6-c...@perl.org
On Tue, Feb 22, 2005 at 08:35:49PM +0800, Autrijus Tang wrote:
> jn Tue, Feb 22, 2005 at 10:54:26AM -0000, Rafael Garcia-Suarez wrote:
> > I had this silly idea, to try to add %ENV to pugs. That would be an
> > interesting exercise. So I can write CGI scripts. Maybe. But I don't
> > know what's the Right way to do it in Perl 6. Any hints ?
>
> In Perl6 I think you do it by populating the %*ENV hash, when the
> script is first run.

This might initially work for read-only access/testing, but in

the long run I suspect that %*ENV will be tied directly to the
C putenv/getenv calls or their Parrot/other equivalents.
Assigning to %*ENV should change the environment for any scripts
invoked from Perl 6.

(This also eliminates the runtime overhead of "populating %*ENV"


when it's not going to be used by a particular script.)

Pm

Rafael Garcia-Suarez

unread,
Feb 22, 2005, 10:17:53 AM2/22/05
to Autrijus Tang, perl6-c...@perl.org
Autrijus Tang wrote:
> jn Tue, Feb 22, 2005 at 10:54:26AM -0000, Rafael Garcia-Suarez wrote:
> > I had this silly idea, to try to add %ENV to pugs. That would be an
> > interesting exercise. So I can write CGI scripts. Maybe. But I don't
> > know what's the Right way to do it in Perl 6. Any hints ?
>
> In Perl6 I think you do it by populating the %*ENV hash, when the
> script is first run. To add it, hack Main.hs line 102 to add a new
> SGlobal symbol of a VHash. If you already have a list of pairs "x",
> it is as simple as:
>
> VHash $ MkHash (listToFM x)

Here's a patch to add this. It's heavily cargo-culted, I need to read
some docs about haskell some day. As I wasn't able to get FiniteMaps to
work I implemented my own kludgy function to flatten pairs for the hash.
Also I suspect that the type of the internal thingy in %*ENV might not
be right, so you may want to turn it in a VHash instead (I haven't found
any difference).

Comes with tests. Note that this %*ENV is not magical. It should be
sufficient to write simple http-GET CGI scripts, though.

Index: t/op/magic.t
===================================================================
--- t/op/magic.t (revision 0)
+++ t/op/magic.t (revision 0)
@@ -0,0 +1,13 @@
+# Tests for magic variables
+
+use v6;
+
+say "1..2";
+
+# Tests for %*ENV
+
+# it must not be empty at startup
+if (0 + %*ENV.keys > 0) { say "ok 1"; } else { say "not ok 1"; }
+
+# PATH is usually defined. But this test is not portable
+if %*ENV{"PATH"} ne "" { say "ok 2"; } else { say "not ok 2"; }
Index: MANIFEST
===================================================================
--- MANIFEST (revision 170)
+++ MANIFEST (working copy)
@@ -71,6 +71,7 @@
t/op/hash.t
t/op/inc.t
t/op/join.t
+t/op/magic.t
t/op/pair.t
t/op/pop.t
t/op/push.t
Index: src/Main.hs
===================================================================
--- src/Main.hs (revision 170)
+++ src/Main.hs (working copy)
@@ -22,6 +22,7 @@
import Parser
import Help
import Pretty
+import Posix

main :: IO ()
main = do
@@ -92,14 +93,20 @@
runFile file = do
withArgs [file] main

+flattenPairs :: [(x,x)] -> [x]
+flattenPairs [] = []
+flattenPairs ((a,b):q) = [a,b] ++ flattenPairs q
+
runProgramWith :: (Env -> Env) -> (Val -> IO ()) -> VStr -> [VStr] -> String -> IO ()
runProgramWith fenv f name args prog = do
+ environ <- getEnvironment
env <- emptyEnv
[ Symbol SGlobal "@*ARGS" (Val $ VList $ map VStr args)
, Symbol SGlobal "@*INC" (Val $ VList [])
, Symbol SGlobal "$*PROGNAME" (Val $ VStr name)
-- , Symbol SGlobal "$*STDIN" (Val $ VStr str)
, Symbol SGlobal "$*END" (Val VUndef)
+ , Symbol SGlobal "%*ENV" (Val $ VList $ map VStr $ flattenPairs environ)
]
-- str <- return "" -- getContents
let env' = runRule (fenv env) id ruleProgram prog
Index: src/Posix.hs
===================================================================
--- src/Posix.hs (revision 170)
+++ src/Posix.hs (working copy)
@@ -21,9 +21,11 @@
rename,
removeLink,
sleep,
+ getEnvironment,
) where

#ifdef PUGS_HAVE_POSIX
+import System.Posix.Env
import System.Posix.Files
import System.Posix.Process
import System.Posix.Unistd
@@ -47,4 +49,7 @@
sleep :: Int -> IO ()
sleep _ = fail "'sleep' not implemented on this platform."

+getEnvironment :: IO [(String, String)]
+getEnvironment = []
+
#endif

Autrijus Tang

unread,
Feb 22, 2005, 12:54:40 PM2/22/05
to Rafael Garcia-Suarez, Autrijus Tang, perl6-c...@perl.org
On Tue, Feb 22, 2005 at 04:17:53PM +0100, Rafael Garcia-Suarez wrote:
> Here's a patch to add this. It's heavily cargo-culted, I need to read
> some docs about haskell some day. As I wasn't able to get FiniteMaps to
> work I implemented my own kludgy function to flatten pairs for the hash.
> Also I suspect that the type of the internal thingy in %*ENV might not
> be right, so you may want to turn it in a VHash instead (I haven't found
> any difference).

Thanks, indeed a list of pairs may be casted, in Pugs internal, as a
hash at any time. To cast into VHash, use listToFM:

VHash . MkHash . listToFM $ [ (VStr k, VStr v) | (k, v) <- environ ]

But otherwise, the patch is clean. Applied, thanks!

/Autrijus/

0 new messages