POV-Ray : Newsgroups : povray.general : #local access Server Time
8 Aug 2024 12:26:08 EDT (-0400)
  #local access (Message 1 to 10 of 16)  
Goto Latest 10 Messages Next 6 Messages >>>
From: Rune
Subject: #local access
Date: 1 Mar 2001 16:07:24
Message: <3a9eba0c@news.povray.org>
Consider the code below:

box{x,x}
#macro Mother(Input)
   #local Var = Input;
   Child()
#end
#macro Child()
   #local Var = Var+1; // line 7
   Var
#end
#declare Number = Mother(1);
#debug str(Number,0,0)

It generates an error at line 7.
But if the Child macro is changed to:

#macro Child()
   #local Var2 = Var+1; // line 7
   Var2
#end

The code works fine. That is, the mother variable "Var" is only accessible
if it is not currently being assigned at a lower level. But I thought a
variable was not supposed to interfere with anything before the assignment
was completed (semi-colon reached) ?  Or is it?

On an unrelated note: Isn't there any way I can make the child macro handle
and update a variable created in the mother macro, besides making the
variable global? I'm afraid not?

Rune
--
\ Include files, tutorials, 3D images, raytracing jokes,
/ The POV Desktop Theme, and The POV-Ray Logo Contest can
\ all be found at http://rsj.mobilixnet.dk (updated January 28)
/ Also visit http://www.povrayusers.org


Post a reply to this message

From: Ron Parker
Subject: Re: #local access
Date: 1 Mar 2001 16:26:36
Message: <slrn99tfke.vj6.ron.parker@fwi.com>
On Thu, 1 Mar 2001 22:04:36 +0100, Rune wrote:
>   #local Var = Var+1; // line 7
              ^ When the parser gets here, it sees that you're declaring a
local and has created a space to put that local in.  It called that space 
"Var".

>   #local Var = Var+1; // line 7
                    ^ When it gets here, it sees that you are trying to use
a variable called "Var" which it goes and looks up.  It finds the one you're
currently creating and returns an error because it hasn't been defined yet.

Presumably this could be changed to work the way you expect, but I'd hesitate
to call it a bug.

>On an unrelated note: Isn't there any way I can make the child macro handle
>and update a variable created in the mother macro, besides making the
>variable global? I'm afraid not?

Pass the variable in as a parameter.  POV 3.1g treats parameters as references 
when you pass identifiers, unless they're strings (that last part is a bug.)

-- 
Ron Parker   http://www2.fwi.com/~parkerr/traces.html
My opinions.  Mine.  Not anyone else's.


Post a reply to this message

From: Ron Parker
Subject: Re: #local access
Date: 1 Mar 2001 16:31:03
Message: <slrn99tfsq.vjb.ron.parker@fwi.com>
On 1 Mar 2001 16:26:36 -0500, Ron Parker wrote:
>Presumably this could be changed to work the way you expect, but I'd hesitate
>to call it a bug.

Actually, I take that back.  Even if it did find the Parent's "Var" when it
tried to figure out what "Var + 1" means, it would still put the result in
a local variable called Var which would be thrown out when Child() returned,
leaving Parent()'s version set to what it was.  Any other behavior would 
make #local meaningless.

-- 
Ron Parker   http://www2.fwi.com/~parkerr/traces.html
My opinions.  Mine.  Not anyone else's.


Post a reply to this message

From: Ron Parker
Subject: Re: #local access
Date: 1 Mar 2001 16:43:49
Message: <slrn99tgkn.vji.ron.parker@fwi.com>
On Thu, 1 Mar 2001 22:04:36 +0100, Rune wrote:
>On an unrelated note: Isn't there any way I can make the child macro handle
>and update a variable created in the mother macro, besides making the
>variable global? I'm afraid not?

I should probably read the docs more.  See the section called "Identifier
Name Collisions":

The complication comes when trying to assign a new value to an identifier 
at one level that was declared local at an earlier level. Suppose inside 
myinc.inc you do...

 #local D = 789;

If you are inside myinc.inc and you want to increment D by one, you might t
ry to do...

 #local D = D + 1;

but if you try to do that inside MyMacro you'll create a new D which is local 
to MyMacro and not the D which is external to MyMacro but local to myinc.inc. 
[actually, as you've noticed, this is an error.] Therefore you've said "create 
a MyMacro D from the value of myinc.inc's D plus one". That's probably not 
what you wanted. Instead you should do...

 #declare D = D + 1;

You might think this creates a new D that is global but it actually increments 
the myinc.inc version of D. Confusing isn't it?  Here are the rules:

1.) When referencing an identifier, you always get the most recent, most local 
version. By "referencing" we mean using the value of the identifier in a 
POV-Ray statement or using it on the right of an equals sign in either a 
#declare or #local.

2.) When declaring an identifier using the #local keyword, the identifier 
which is created or has a new value assigned, is ALWAYS created at the current 
nesting level of macros or include files.

3.) When declaring a NEW, NON-EXISTANT identifier using #declare, it is 
created as fully global. It is put in the symbol table of the main scene file.

4.) When ASSIGNING A VALUE TO AN EXISTING identifier using #declare, it 
assigns it to the most recent, most local version at the time.

In summary, #local always means "the current level", and #declare means 
"global" for new identifiers and "most recent" for existing identifiers.



-- 
Ron Parker   http://www2.fwi.com/~parkerr/traces.html
My opinions.  Mine.  Not anyone else's.


Post a reply to this message

From: Chris Huff
Subject: Re: #local access
Date: 1 Mar 2001 16:49:29
Message: <chrishuff-D0F5D2.16474901032001@news.povray.org>
In article <3a9eba0c@news.povray.org>, "Rune" <run### [at] inamecom> 
wrote:

> The code works fine. That is, the mother variable "Var" is only 
> accessible if it is not currently being assigned at a lower level. 
> But I thought a variable was not supposed to interfere with anything 
> before the assignment was completed (semi-colon reached) ?  Or is it?

I think this is a bug (if I understand what you mean)...variables inside 
a macro should not affect #local variables outside it, even in a macro 
that calls it.


> On an unrelated note: Isn't there any way I can make the child macro 
> handle and update a variable created in the mother macro, besides 
> making the variable global? I'm afraid not?

Other than having it be the return value? Pass it as a parameter...

#macro Child(ChildVar)
   #local ChildVar = ChildVar + 1; // line 7
   (ChildVar)
#end
#macro Mother(Input)
   #local Var = Input;
   Child(Var)
#end

-- 
Christopher James Huff
Personal: chr### [at] maccom, http://homepage.mac.com/chrishuff/
TAG: chr### [at] tagpovrayorg, http://tag.povray.org/

<><


Post a reply to this message

From: Rune
Subject: Re: #local access
Date: 1 Mar 2001 18:45:51
Message: <3a9edf2f@news.povray.org>
"Ron Parker" wrote:
> but if you try to do that inside MyMacro you'll create a new D
> which is local to MyMacro and not the D which is external to
> MyMacro but local to myinc.inc.
> [actually, as you've noticed, this is an error.]

I don't think that's an error. I might want to create a variable local to
the macro. And the macro may be called from outside the inc. But even though
it is not an error, it still is a problem in many cases. Which bring us to
the 4th of the rules you stated:

> 4.) When ASSIGNING A VALUE TO AN EXISTING identifier using #declare,
> it assigns it to the most recent, most local version at the time.

I didn't know that! That's great! It solves my problems! Thanks!

Rune
--
\ Include files, tutorials, 3D images, raytracing jokes,
/ The POV Desktop Theme, and The POV-Ray Logo Contest can
\ all be found at http://rsj.mobilixnet.dk (updated January 28)
/ Also visit http://www.povrayusers.org


Post a reply to this message

From: Rune
Subject: Re: #local access
Date: 1 Mar 2001 18:45:54
Message: <3a9edf32@news.povray.org>
"Ron Parker" wrote:
> Even if it did find the Parent's "Var" when it tried to
> figure out what "Var + 1" means, it would still put the
> result in a local variable called Var which would be
> thrown out when Child() returned, leaving Parent()'s
> version set to what it was.

As I would expect.

> Any other behavior would make #local meaningless.

Agreed.

Rune
--
\ Include files, tutorials, 3D images, raytracing jokes,
/ The POV Desktop Theme, and The POV-Ray Logo Contest can
\ all be found at http://rsj.mobilixnet.dk (updated January 28)
/ Also visit http://www.povrayusers.org


Post a reply to this message

From: Chris Huff
Subject: Re: #local access
Date: 2 Mar 2001 07:55:56
Message: <chrishuff-923E21.07541602032001@news.povray.org>
In article <3a9edf2f@news.povray.org>, "Rune" <run### [at] inamecom> 
wrote:

> > 4.) When ASSIGNING A VALUE TO AN EXISTING identifier using #declare,
> > it assigns it to the most recent, most local version at the time.
> 
> I didn't know that! That's great! It solves my problems! Thanks!

This does not seem right...#declare should always create a global 
variable. It is certainly unintuitive...to me at least.
I have suggested something before that would solve this, and it's 
partially implemented in a patch (and included in the most recent 
version of MegaPOV): the #set directive, which will assign to the most 
local version of a variable, but will not create a new identifier. You 
would use #declare and #local to *create* global and local variables, 
and #set to modify them.
This seems like a cleaner and less confusing system...

-- 
Christopher James Huff
Personal: chr### [at] maccom, http://homepage.mac.com/chrishuff/
TAG: chr### [at] tagpovrayorg, http://tag.povray.org/

<><


Post a reply to this message

From: Ron Parker
Subject: Re: #local access
Date: 2 Mar 2001 08:18:51
Message: <slrn99v7ds.vvg.ron.parker@fwi.com>
On Fri, 02 Mar 2001 07:54:16 -0500, Chris Huff wrote:
>In article <3a9edf2f@news.povray.org>, "Rune" <run### [at] inamecom> 
>wrote:
>
>> > 4.) When ASSIGNING A VALUE TO AN EXISTING identifier using #declare,
>> > it assigns it to the most recent, most local version at the time.
>> 
>> I didn't know that! That's great! It solves my problems! Thanks!
>
>This does not seem right...#declare should always create a global 
>variable. It is certainly unintuitive...to me at least.

#declare always CREATES a global variable, but it doesn't always MODIFY one.
That's the way it's always been, and it's documented behavior.  It seems 
intuitive to me: if you use #declare to modify a variable, you're guaranteed
to modify the variable that you would have seen when you interrogated it.
Wouldn't it suck to do it otherwise if you had something like this?

#macro ForceVarInBounds()
  #ifdef(Var)
    #if (Var < 0) #declare Var=0; #end
    #if (Var > 255) #declare Var=255; #end
  #end // ifdef
#end // macro

#macro DoStuff() {
  #local Var=SomeFunction();
  ForceVarInBounds()
  DoSomethingCriticalWithVar()
#end // macro

Oops... The ForceVarInBounds macro didn't do what you thought it would.
Yeah, I know, we shouldn't use global variables.  That being the case, 
this will never be a problem.

>This seems like a cleaner and less confusing system...

It doesn't seem less confusing to me.  If you implement it, I forsee lots of

#ifdef (foo)
  #set foo = SomeComplicatedMacro();
#else
  #declare foo = SomeComplicatedMacro();
#end



>
>-- 
>Christopher James Huff
>Personal: chr### [at] maccom, http://homepage.mac.com/chrishuff/
>TAG: chr### [at] tagpovrayorg, http://tag.povray.org/
>
><><


-- 
Ron Parker   http://www2.fwi.com/~parkerr/traces.html
My opinions.  Mine.  Not anyone else's.


Post a reply to this message

From: Rune
Subject: Re: #local access
Date: 2 Mar 2001 12:15:04
Message: <3a9fd518@news.povray.org>
"Ron Parker" wrote:
> It seems intuitive to me: if you use #declare to modify a variable,
> you're guaranteed to modify the variable that you would have seen
> when you interrogated it.
> Wouldn't it suck to do it otherwise if you had something like this?
>
> #macro ForceVarInBounds()
>   #ifdef(Var)
>     #if (Var < 0) #declare Var=0; #end
>     #if (Var > 255) #declare Var=255; #end
>   #end // ifdef
> #end // macro
>
> #macro DoStuff() {
>   #local Var=SomeFunction();
>   ForceVarInBounds()
>   DoSomethingCriticalWithVar()
> #end // macro

Exactly!

That's basically what I needed to do, and I was very pleased to find out
that it could be done in an easy manner. I personally find it intuitive too.

> That's the way it's always been, and it's documented behavior.

I see now that the rules you stated are taken right out of the documentation
in the section "Identifier name collisions". I should reread the whole
documentation once in a while...

I did found a bug though. In the documentation this is stated:

> Suppose inside myinc.inc you do...
>
>  #local D = 789;
>
> If you are inside myinc.inc and you want to increment D by
> one, you might try to do...
>
>  #local D = D + 1;
>
> but if you try to do that inside MyMacro you'll create a new
> D which is local to MyMacro and not the D which is external
> to MyMacro but local to myinc.inc.

POV-Ray does not work as the documentation states. It works like this:

> (...)
> but if you try to do that inside MyMacro you'll get the error
> message "Cannot assign uninitialized identifier".

Whether this is a bug in POV-Ray or in the documentation I will let others
decide.

I personally think that POV-Ray should keep its current functionality since
it prevents the user from making stupid mistakes based on misconceptions,
such as the example in the documentation.

Rune
--
\ Include files, tutorials, 3D images, raytracing jokes,
/ The POV Desktop Theme, and The POV-Ray Logo Contest can
\ all be found at http://rsj.mobilixnet.dk (updated January 28)
/ Also visit http://www.povrayusers.org


Post a reply to this message

Goto Latest 10 Messages Next 6 Messages >>>

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.