You are here

Script-fu variable usage (and apparent MIS-usage)

Hello,

I'm very much new to scripting for Gimp and had high hopes of being able to automate the construction/assembly of 2000-3000 images using programmatically generated scripts. Knowing my own limitations, it seemed prudent to begin slowly and build on what I learned in a step-by-step manner. I followed through the tutorial(s) for Script-fu and thought it was about time to strike out and try a bit on my own.

I've made several simple (simple in a general sense, not so simple when they fail ...) scripts and have been using the Script-fu console to call them so I can see directly and incrementally what works. As I'm using them exclusively from the console, I'm not including script registration info at the end of them.

This first small script works fine and creates the image as desired:

(define (script-fu_justmakeImage)

(gimp-display-new (car (gimp-image-new 800 600 0)))

)

As my intent is to add a layer or two and assemble some text areas and ultimately flatten and save the images with unique names, I wanted to begin to build toward that by keeping track of image ID's and layer ID's (drawables?) so later when saving, I could name them appropriately and refer to them successfully. With that in mind, I tried the following:


(define (script-fu_makeImage_let)

(let (
(thisImage (car (gimp-image-new 800 600 0)))
(thisLayer (car (gimp-image-get-active-layer thisImage)))
)
)

(gimp-display-new thisImage)

)

This code throws an error thus:

> (script-fu_makeImage_let)
Error: eval: unbound variable: thisImage

I've also tried setting the variables as global as below - understanding that global might not be ideal but I'd like to see something work and so far, nothing has:


(define (script-fu_makeImage_set)

(set! thisImage (gimp-image-new 800 600 0))
(set! thisLayer (gimp-image-get-active-layer thisImage))

(gimp-display-new thisImage)

)

This gets me a similar error though it differs slightly:

> (script-fu_makeImage_set)
Error: set!: unbound variable: thisImage

I've fiddled with both let (and let*) and set and the only time I get a different error is when I make a mistake on parentheses.

I've searched for a wide variety of combinations of scripting and gimp and variable setting and scope and even some of the examples I've found seem similar to (or even identical in some ways) to what I'm trying but I haven't found a definitively up-to-date source that explicitly shows me what I should be doing or what's wrong with what I am doing.

I'm certain the error is mine but I'm utterly at a loss as to what is in fact wrong or where it contradicts a specific document I can locate.

[edit]
I neglected to mention that I'm using GIMP version 2.6.11

[[edit (again)]]

I attempted to respond with thanks to rem a couple of days ago but that note hasn't made it past moderation yet ... so I'd like to say to both rem and saulgoode a hearty and sincere thank you both! The information has been very helpful and I'm well past that particular difficulty now. Of course there are new questions but I know where to look if I should tire of the self study .. thank you again !

(define (script-fu_makeImage_let)

; use let*
(let* (
(thisImage (car (gimp-image-new 800 600 0)))
(thisLayer (car (gimp-image-get-active-layer thisImage)))
)

(gimp-display-new thisImage)
)
; move the closing let bracket here
)

A few tips:
- Use a good syntax highlighting editor
- look into already done working scripts from others, this makes things
much clearer after a while
- a wonderful source for a lot of scripts to learn from is
http://gimpfx-foundry.sourceforge.net/

Greetings Ruediger

When you use 'let' to create your variable assignments, the order in which the assignments are performed is not guaranteed.

For example, the following code may not work because the interpreter may try to define 'y' before 'x' has been defined.

(let (
     (x 10)
     (y x)
     )
  ...
  )

Typically Scheme interpreters will evaluate such 'let' bindings in reverse order, so if you swapped the two lines then things might work -- but this is by no means guaranteed. On a multi-processor system, the two assignments might be performed in parallel on two different processors, so even if this reverse ordering worked on one machine, it might not on another.

The 'let*' form of defining variables guarantees that each assignment is evaluated in sequence and so 'x' (in the above example) will be assigned the value "10" before it is used in 'y's definition.

For someone just starting out with scripting, I would recommend always using the 'let*' form since it works whether or not the order of assignment matters.

As a side note, when posting code on the Plug-in Registry, you can wrap it within [pre] and [/pre] HTML tags (replace the square brackets with less than/greater than symbols). This way your indentation and spacing will be retained.

I attempted to respond with thanks to rem a couple of days ago but that note hasn't made it past moderation yet ... so I'd like to say to both rem and saulgoode a hearty and sincere thank you both! The information has been very helpful and I'm well past that particular difficulty now. Of course there are new questions but I know where to look if I should tire of the self study .. thank you again !
If you wish to ask any questions about scripting, you might find it more convenient to use the GIMP User Group link at the top of the page. I generally visit the Script-fu subforum[1] on a daily basis and would be glad to address any issues you wish to discuss. (The Plug-in Registry is a great resource, especially for the publication of finalized scripts; however, I personally find dedicated forums to be more conducive to exchanging ideas and learning.)

[1] http://gug.criticalhit.dk/viewforum.php?f=8

Subscribe to Comments for "Script-fu variable usage (and apparent MIS-usage)"