discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

Help with variables, scope and method definitions

GH
George Hartzell
Fri, Feb 9, 2018 7:06 PM

I thought that I was having trouble understanding how variables and
include interacted, the lib.scad/hello.scad example didn't make any
sense to me.

While experimenting with it, I substituted the contents of lib.scad
into hello.scad and ran into the same conceptual problem.

So, I seem to have a problem with how variables are defined/used
within modules.

Here's the hello.scad example from [1] with the contents of lib.scad
inserted into it and the three test cases I've been playing with.
Cases 1 and 2 are as described in [1].  Uncomment each test case in
turn to see the output's I'm trying to understand (note that test case
3 has bits in two locations...).

// case 1
// j = 4;

// case 3
// j = 0;

i=1;
k=3;
module x() {
    echo("hello world");
    echo("i=",i,"j=",j,"k=",k);
}

// case 2
// j=4;

// case 3
// j=42;

x();
i=5;
x();
k=j;
x();

For case 1, k is 4 in the call to x, which I explain to myself as "The
value of k is assigned at compile time and it gets the last/only value
of j."  Case 3 is a consistent with this; although j was 0 when the module x
was compiled (or parsed?) k uses the last compile time value of j, 42.

I can't explain to myself what's happening to cause k to be undef in
case 2.  I think that this bit from [1] is supposed to explain it:

When there are multiple assignments it takes the last value, but
assigns when the variable is first created.

but I still can't get any traction.

Might someone try an alternative explanation?

g.

I thought that I was having trouble understanding how variables and include interacted, the lib.scad/hello.scad example didn't make any sense to me. While experimenting with it, I substituted the contents of lib.scad into hello.scad and ran into the same conceptual problem. So, I seem to have a problem with how variables are defined/used within modules. Here's the hello.scad example from [1] with the contents of lib.scad inserted into it and the three test cases I've been playing with. Cases 1 and 2 are as described in [1]. Uncomment each test case in turn to see the output's I'm trying to understand (note that test case 3 has bits in two locations...). ```scad // case 1 // j = 4; // case 3 // j = 0; i=1; k=3; module x() { echo("hello world"); echo("i=",i,"j=",j,"k=",k); } // case 2 // j=4; // case 3 // j=42; x(); i=5; x(); k=j; x(); ``` For case 1, k is 4 in the call to x, which I explain to myself as "The value of k is assigned at compile time and it gets the last/only value of j." Case 3 is a consistent with this; although j was 0 when the module x was compiled (or parsed?) k uses the last compile time value of j, 42. I can't explain to myself what's happening to cause k to be undef in case 2. I think that this bit from [1] is supposed to explain it: > When there are multiple assignments it takes the last value, but > assigns when the variable is first created. but I still can't get any traction. Might someone try an alternative explanation? g. [1]: https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#Variables_2
GH
George Hartzell
Fri, Feb 9, 2018 7:11 PM

Whoops:  My first paragraph should have included the link to the
example.  It's the same example I discussed and linked to further on
in the message. If I could go back in time, I'd change the first
paragraph to read:

I thought that I was having trouble understanding how variables and
include interacted, the lib.scad/hello.scad example 1 didn't make any
sense to me.

....

Sorry if it wasn't clear.

g.

Whoops: My first paragraph should have included the link to the example. It's the same example I discussed and linked to further on in the message. If I could go back in time, I'd change the first paragraph to read: > I thought that I was having trouble understanding how variables and > include interacted, the lib.scad/hello.scad example [1] didn't make any > sense to me. > > .... > > [1]: https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#Variables_2 Sorry if it wasn't clear. g.
R
runsun
Fri, Feb 9, 2018 7:42 PM

Although I can't say I understand how it works behind the scene, my
explanation in
http://forum.openscad.org/quot-Ignoring-unknown-variable-quot-issue-td13156i20.html#a13321
might shed some light.

The OpenScad scans the code twice. After the first scan, your code becomes:

After 1st scan wrote

// case 1
// j = 4;

// case 3
// j = 0;

i=1;
k=j ;  //<============ NOTE THIS. At this time j hasn't bee defined yet.
module x() {
echo("hello world");
echo("i=",i,"j=",j,"k=",k);
}


$  Runsun Pan, PhD $ libs: doctest , faces ( git ), offline doc ( git ), runscad.py ( 2 , git ), synwrite ( 2 );   $ tips: Collection of tips on github

--
Sent from: http://forum.openscad.org/

Although I can't say I understand how it works behind the scene, my explanation in http://forum.openscad.org/quot-Ignoring-unknown-variable-quot-issue-td13156i20.html#a13321 might shed some light. The OpenScad scans the code twice. After the first scan, your code becomes: After 1st scan wrote > // case 1 > // j = 4; > > // case 3 > // j = 0; > > i=1; > k=j ; //<============ NOTE THIS. At this time j hasn't bee defined yet. > module x() { > echo("hello world"); > echo("i=",i,"j=",j,"k=",k); > } ----- $ Runsun Pan, PhD $ libs: doctest , faces ( git ), offline doc ( git ), runscad.py ( 2 , git ), synwrite ( 2 ); &nbsp; $ tips: Collection of tips on github -- Sent from: http://forum.openscad.org/
MK
Marius Kintel
Sat, Feb 10, 2018 11:32 PM

On Feb 9, 2018, at 2:06 PM, George Hartzell hartzell@alerce.com wrote:

Might someone try an alternative explanation?

Without commenting specifically on your program, I can offer this:

  • All assignments in a scope is hoisted to the top of that scope (i.e. all assignment are performed before any other statements)
  • All assignments are performed in their declared order
  • If an assignment is made twice, the second assignment takes precedence, but the order does not change.

The last point is probably what is confusing you.
The reason we did it this way was that, at the time is was implemented, it was the quickest way of supporting overriding assignments on the cmd-line.

-Marius

> On Feb 9, 2018, at 2:06 PM, George Hartzell <hartzell@alerce.com> wrote: > > Might someone try an alternative explanation? > Without commenting specifically on your program, I can offer this: * All assignments in a scope is hoisted to the top of that scope (i.e. all assignment are performed before any other statements) * All assignments are performed in their declared order * If an assignment is made twice, the second assignment takes precedence, but the order does not change. The last point is probably what is confusing you. The reason we did it this way was that, at the time is was implemented, it was the quickest way of supporting overriding assignments on the cmd-line. -Marius
GH
George Hartzell
Sat, Feb 10, 2018 11:57 PM

Marius Kintel writes:

On Feb 9, 2018, at 2:06 PM, George Hartzell hartzell@alerce.com wrote:

Might someone try an alternative explanation?

Without commenting specifically on your program, I can offer this:

  • All assignments in a scope is hoisted to the top of that scope (i.e. all assignment are performed before any other statements)
  • All assignments are performed in their declared order
  • If an assignment is made twice, the second assignment takes precedence, but the order does not change.

The last point is probably what is confusing you.
The reason we did it this way was that, at the time is was
implemented, it was the quickest way of supporting overriding
assignments on the cmd-line.

-Marius

Thanks for the feedback!

After reading through the responses and trying simpler and simpler
examples, I've realized that it's not an issue about include or
module or echo or ...

It's simply this:

j=1;
k=3;
k=j;

This works; the first assignment to k is replaced by the second and
since j is defined/declared earlier all is well.

k=3;
j=1;
k=j;

This results in WARNING: Ignoring unknown variable 'j'; the first
assignment to k is replaced by the second and/but when it is executed
j is unknown.

In simple setting this already made sense but I was letting the
modules and the includes cloud my judgement.

Thanks for the explanations!

g.

Marius Kintel writes: > > On Feb 9, 2018, at 2:06 PM, George Hartzell <hartzell@alerce.com> wrote: > > > > Might someone try an alternative explanation? > > > Without commenting specifically on your program, I can offer this: > * All assignments in a scope is hoisted to the top of that scope (i.e. all assignment are performed before any other statements) > * All assignments are performed in their declared order > * If an assignment is made twice, the second assignment takes precedence, but the order does not change. > > The last point is probably what is confusing you. > The reason we did it this way was that, at the time is was > implemented, it was the quickest way of supporting overriding > assignments on the cmd-line. > > -Marius Thanks for the feedback! After reading through the responses and trying simpler and simpler examples, I've realized that it's not an issue about include or module or echo or ... It's simply this: ```scad j=1; k=3; k=j; ``` This works; the first assignment to k is replaced by the second and since j is defined/declared earlier all is well. ```scad k=3; j=1; k=j; ``` This results in `WARNING: Ignoring unknown variable 'j'`; the first assignment to k is replaced by the second and/but when it is executed j is unknown. In simple setting this already made sense but I was letting the modules and the includes cloud my judgement. Thanks for the explanations! g.