[Closed] Weird for-in loop behavior
Hello, Everybody!
There is a weird ‘for – in’ loop behavior:
struct greeter (
prefix
,fn say x = prefix + ", " + x
)
greets = for el in #( "Hello" ,"Good Morning" ,"Hi" ) collect (greeter el).say
-- Now I have a collection of instantiated structure's methods
-- And I can call them in a 'for - to' loop:
-- Ok, people, say hello to Peter
for i=1 to greets.count do print ( greets[i] "Peter" )
The output:
"Hello, Peter"
"Good Morning, Peter"
"Hi, Peter"
OK
But in case of ‘for – in’ loop, each method ‘el’ somehow becomes uninstantiated:
-- Ok, people, say hello to Peter in 'for-el' loop way
for el in greets do print ( el "Peter" )
The code above throws an exception:
-- Error occurred in say()
-- Frame:
-- x: "Peter"
-- called in el loop
-- Frame:
-- el: say()
-- Runtime error: Struct member access requires instance: prefix
I have 2014 max design.
Can anyone, please, confirm the same situation in 2015 maxscript?
i can confirm that the code you’ve posted is written on a language that similar to the maxscript. but it can’t work be ran by the max system.
what should we do?
option #1: you can fix the code and repeat the question if it will be necessary
option #2: we fix the code and tell you what was wrong
Hmm… Sorry, it is my first time posting here.
Maybe I shouldn’t have mixed the code with an output.
I have fixed the original post.
now it’s a mxs
it’s pretty … hmm… original (i don’t want to say “weird”) using of structures and pointers to mxs function but the code is valid now
i think it’s much safer to collect instances of the structure than pointers of a structure method…
struct Greetings
(
how,
fn greet who = format "%, %!
" how who
)
ss = for how in #("Hi", "Nice to see you", "F*ck you") collect (Greetings how)
for s in ss do s.greet "Bob"
has to work i hope
Thanks. Yes, it works, of course.
My goal was to operate on functions without any additional conventions on how to name things.
The caller might not want to know what is the name of the method, ‘greet’ or ‘say’ or anything else.
Just call: s “Bob”
But I think that the functional way might be … hmm … original for mxs
it’s original but not invalid for mxs.
it might be an issue with garbage collection. that’s why i told about a safety.
but the way below has to work…
collect struct instances the way i did above
after that:
gg = for s in ss collect s.greet
for g in gg do g "Bob"
i will be surprised if it not works
i will be surprised if it not works
It doesn’t:
-- Error occurred in greet()
-- Frame:
-- who: "Bob"
-- called in g loop
-- Frame:
-- g: greet()
-- Runtime error: Struct member access requires instance: how
Looks like it doesn’t matter what the method does.
It is the fact we iterate with ‘for-in’ loop that makes the method uninstantiated.
Looks like this is the for-in loop’s automatic dereferencing behaviour that’s leaving the struct functions without the rest of their struct members. Seems dereferencing a pointer to a struct function in general tends to do that, resulting in the same exact error.
Can’t think of anything other than putting the the function one step further out of reach of the dereferencing, like putting it into its own array:
gg = for s in ss collect #(s.greet)
for g in gg do g[1] "Bob"
But that’s pretty much just manually iterating over the initial array again, but uglier. : /