View Full Version : Should Eval work as I'm expecting it to?


hello_hello
7th November 2017, 20:50
I'm using Eval in order to prevent Avisynth from processing some slow tasks unless it needs to (or so I thought). The first part of the function looks like this (not exact, but simplified to demonstrate the problem), and the line I'm fussed about is the one highlighted in blue.

function Test(clip c, int "OutWidth", int "OutHeight", int "CL", int "CT", int "CR", int "CB", bool "Auto", int "Cthresh", int "Cstart", int "Csample", val "PicDAR", int "Mod", val "InDAR", bool "Borders", bool "FrostyBorders", bool "Resize", bool "HResize", bool "CleanBorders", int "Preview", val "Bcolor", bool "Info")
{

Resize = default(Resize, true)
HResize = default(HResize, true)
OutWidth = (HResize == false) ? (0) : default(OutWidth, 0)
OutHeight = (HResize == false) ? (0) : default(OutHeight, 0)
CL = default(CL, 0)
CT = default(CT, 0)
CR = default(CR, 0)
CB = default(CB, 0)
Float_CL = float(CL)
Float_CT = float(CT)
Float_CR = float(CR)
Float_CB = float(CB)
Auto = default(Auto, false)
Cthresh = default(Cthresh, 30)
Cstart = default(Cstart, 250)
Csample = default(Csample, 5)
PicDAR = default(PicDAR, float(0))
Mod = default(Mod, 4)
Float_Mod = float(Mod)
InDAR = default(InDAR, float(c.width) / float(c.height))
Borders = default(Borders, false)
FrostyBorders = default(FrostyBorders, false)
Bordered = (Borders == true) || (FrostyBorders == true) ? true : false
CleanBorders = default(CleanBorders, false)
Preview = default(Preview, 0)
Bcolor = default(Bcolor, $000000)
Info = default(Info, false)
ACpreview = (Preview == 2) ? (0) : (Preview)

(Auto == true) && (ACpreview == 1) ? \
Eval("""
Grey_Source = c.Greyscale()
return Grey_Source
""") : \
(Auto == true) ? \
Eval("""
Grey_Source = c.Greyscale()
FFS = Grey_Source
""") : \
Eval("""
FFS = c.crop(CL, CT, CR, CB)
""")
}

Using the above (incomplete) function, if I add the following to a script, I get a b/w version of the clip, as I had expected.

Test(Auto=true, Preview=1)

My question is, why doesn't Avisynth stop at the return line as it does for the above function when I add a little more to it? The following function will result in an "I don't know what FFS means" error. I've added two extra lines. Would that be expected behaviour?

function Test(clip c, int "OutWidth", int "OutHeight", int "CL", int "CT", int "CR", int "CB", bool "Auto", int "Cthresh", int "Cstart", int "Csample", val "PicDAR", int "Mod", val "InDAR", bool "Borders", bool "FrostyBorders", bool "Resize", bool "HResize", bool "CleanBorders", int "Preview", val "Bcolor", bool "Info")
{

Resize = default(Resize, true)
HResize = default(HResize, true)
OutWidth = (HResize == false) ? (0) : default(OutWidth, 0)
OutHeight = (HResize == false) ? (0) : default(OutHeight, 0)
CL = default(CL, 0)
CT = default(CT, 0)
CR = default(CR, 0)
CB = default(CB, 0)
Float_CL = float(CL)
Float_CT = float(CT)
Float_CR = float(CR)
Float_CB = float(CB)
Auto = default(Auto, false)
Cthresh = default(Cthresh, 30)
Cstart = default(Cstart, 250)
Csample = default(Csample, 5)
PicDAR = default(PicDAR, float(0))
Mod = default(Mod, 4)
Float_Mod = float(Mod)
InDAR = default(InDAR, float(c.width) / float(c.height))
Borders = default(Borders, false)
FrostyBorders = default(FrostyBorders, false)
Bordered = (Borders == true) || (FrostyBorders == true) ? true : false
CleanBorders = default(CleanBorders, false)
Preview = default(Preview, 0)
Bcolor = default(Bcolor, $000000)
Info = default(Info, false)
ACpreview = (Preview == 2) ? (0) : (Preview)

(Auto == true) && (ACpreview == 1) ? \
Eval("""
Grey_Source = c.Greyscale()
return Grey_Source
""") : \
(Auto == true) ? \
Eval("""
Grey_Source = c.Greyscale()
FFS = Grey_Source
""") : \
Eval("""
FFS = c.crop(CL, CT, CR, CB)
""")

Blah_Blah = FFS
return c
}

For the second version of the function, the following returns the source clip.
Test()

Thanks.

StainlessS
7th November 2017, 21:11
Last=Eval("""
Grey_Source = c.Greyscale()
return Grey_Source
""")
return Last # Implied

Return Grey_Source is return from the EVAL script,
and the special variable 'Last' is set to the result of that Eval in the parent function.
At the End of the parent function, Last is returned by Default.
In the 2nd script, result Last is then ignored and you return c instead of Last.


Last=Eval("""
Grey_Source = c.Greyscale()
return Grey_Source
""")
return c # ignore Last and return c instead


EDIT: Actually this does work.

Function Fn() {
A=Colorbars.KillAudio
B=A.Subtitle("I AM Clip B")
C=A.Subtitle("I AM Clip C")
A=A.Subtitle("I AM Clip A")

B.Eval(""" # In here Last is B
Z=Last
return C # Comment this line out will produce error, Implicit assigment [EDIT: of C] to Last is undefined (not sure why)
""")
Return StackVertical(Last,Z) # Error HERE, if above 'return C' commented out (Last undefined)
}

Fn # Shows C over B. (Last over Z)


EDIT: Docs
Eval | | Eval(expression [, string "name"])
Eval evaluates an arbitrary expression as if it was placed inside the script at the point of the call to Eval and returns the result of evaluation (either to the variable that is explicitly assigned to or to the last special variable).
You can use Eval to construct and evaluate expressions dynamically inside your scripts, based on variable input data. Below some specific examples are shown but you get the general idea.
Argument name will be shown in the error message besides the script name. Both will be followed with the line number in the script where the error is caused.


EDIT:
Error, Last not defined, no explicit/implicit assignment

A=Colorbars.KillAudio
Eval("""
Z=A
""")
return Last


Success, explicit assignment to Implicit Last

A=Colorbars.KillAudio
Eval("""
Z=A
return z
""")
return Last


Error, Explicit assignment fails

A=Colorbars.KillAudio
Last=Eval("""
Z=A
""")
return Last



Success, explicit assignment to explicit Last

A=Colorbars.KillAudio
Last=Eval("""
Z=A
return z
""")
return Last

hello_hello
8th November 2017, 07:36
Ahhhhhhh.........

Thanks. I think I get it now. I probably should be looking at Eval as a function you create when you're not creating a function, or something like that.....
I expected "return" to be the end of the line even when it's being evaluated, but obviously that's not how it works.

My main motivation for using Eval in the first place was to prevent autocrop.dll from slowing the speed at which the script opens. Using Eval for autocrop seemed to prevent it from slowing things down until it was needed, although even that resulted in something else I didn't quite expect (Which turned out to be wrong. See post #4).

For instance this is similar to the function I was working on:

(Auto == true) && (ACpreview == 1) ? \
Eval("""
Auto_Cropped_Source = c.autocrop(mode=1)
return Auto_Cropped_Source
""") : (Auto == true) ? \
Eval("""
Auto_Cropped_Source = c.autocrop(mode=0)
""") : \
Eval("""
Cropped_Source = c.crop(CL, CT, CR, CB)
""")

Auto_Cropped_Source_Width = (Auto == false) ? width(c) : width(Auto_Cropped_Source)
Auto_Cropped_Source_Height = (Auto == false) ? height(c) : height(Auto_Cropped_Source)

But when using Test(auto=false) in a script, Avisynth complains about not knowing what "Auto_Cropped_Source" means, and I don't quite understand why it cares or needs to know until Test(auto=true), when it's meaning would be revealed. The solution seems to be to define "Auto_Cropped_Source" above Eval so Avisynth doesn't complain, then when Test(auto=true), the meaning of "Auto_Cropped_Source" is updated.
I guess I'm still learning my way around the idiosyncrasies.

Cheers.

Gavino
8th November 2017, 10:44
For instance this is similar to the function I was working on:
(Auto == true) && (ACpreview == 1) ? \
Eval("""
Auto_Cropped_Source = c.autocrop(mode=1)
return Auto_Cropped_Source
""") : (Auto == true) ? \
Eval("""
Auto_Cropped_Source = c.autocrop(mode=0)
""") : \
Eval("""
Cropped_Source = c.crop(CL, CT, CR, CB)
""")

Auto_Cropped_Source_Width = (Auto == false) ? width(c) : width(Auto_Cropped_Source)
Auto_Cropped_Source_Height = (Auto == false) ? height(c) : height(Auto_Cropped_Source)

But when using Test(auto=false) in a script, Avisynth complains about not knowing what "Auto_Cropped_Source" means ...
No, that should work perfectly well.
The code inside a conditional branch is evaluated only if that branch is selected.
However, if you change the last two lines to
Auto_Cropped_Source_Width = width(Auto_Cropped_Source)
Auto_Cropped_Source_Height = height(Auto_Cropped_Source)
(thus removing the conditional test on auto)
you will get that error when auto is false, because Auto_Cropped_Source has not been set in the preceding code.

hello_hello
8th November 2017, 11:12
Maybe I confused myself. I changed quite a few things when I was experimenting yesterday. I'll try it again and report back as to whether I was being silly.

Thanks.

raffriff42
8th November 2017, 14:23
By the way, today I learned that Eval can report the error line within the evaluated string - if you use the name argument:
ColorBars
A=Subtitle("A", size=Height, align=2)
#@ function Eval(expression [, string name])
Eval("""
A
foo("bar") ## error!
""", "eval_test_1")
return Last...results in the error message: Script error: there is no function named "foo"
(eval_test_1, line 3)
(E:\_test.avs, line 6)
note line 6 is the line where Eval closes within the parent script.

hello_hello
8th November 2017, 18:40
Thanks raffriff42. That's interesting, it"ll definitely come in handy. No more banging my head on the desk wondering "which $#@$ line is the error on?"

Gavino, yes you're correct and what I said in post #3 was wrong. I think I'd edited the script one time too many and confused myself.

Thanks guys.

StainlessS
8th November 2017, 19:12
By the way, today I learned that Eval can report the error line

Me too, only noticed when copy/pasting the doc text, never seen used before, always thought eval errors were a bit of a pig to debug, not any more :)

real.finder
8th November 2017, 21:10
same here, I was remove the eval("") sometimes to debug, thanks raffriff42