Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

strange Module: linkedlistmodule #656

Closed
PhoenixZeng opened this issue May 16, 2018 · 8 comments
Closed

strange Module: linkedlistmodule #656

PhoenixZeng opened this issue May 16, 2018 · 8 comments
Labels

Comments

@PhoenixZeng
Copy link

class Path
    use LinkedListModule
    static Path top = new Path(main_top,Way.Top)
    static Path left = new Path(main_left,Way.Left)
    static Path right = new Path(main_right,Way.Right)
    static Path bottom = new Path(main_bottom,Way.Bottom)
    construct(Rects start,Way way)
        this.way = way
        this.start = start
        print("->init path"+Path.size.toString())  // right here 
    static function getSize() returns int
        return Path.size
init
    doAfter(1)->
        print(Path.size) // 0 
        print(Path.getSize()) // 0 why? the function get the size from the class 
        Path top = new Path(main_top,Way.Top)
        Path left = new Path(main_left,Way.Left)
        print(Path.size) // 2 why?
        print(Path.getSize()) // 2

well . for i in class(which use the linkedlist) used good. But it's very strange to use it outside of the class (looks like only work when new Instance in same function)

@PhoenixZeng

This comment has been minimized.

@PhoenixZeng PhoenixZeng changed the title strange Module`s variables strange Module: linkedlistmodule May 16, 2018
@Frotty Frotty added the bug label May 16, 2018
@Frotty
Copy link
Member

Frotty commented May 16, 2018

Yes, there is indeed an issue that I think is not intended. I have reduced your example to a minimal snippet that produces the issue:

package demo
import LinkedListModule
import ClosureTimers

init
    let _top = new Path1()

    doAfter(1) ->
        for i in Path1
            print("OK") // Doesn't print
            

public class Path1
    use LinkedListModule
    construct()
        print("init path" + Path1.size.toString())

This produces:

function construct_Path1_LinkedListModule takes integer this_48 returns nothing
	set LinkedListModule_size_3 = LinkedListModule_size_3 + 1
	if LinkedListModule_size_3 == 1 then
		set LinkedListModule_first_4 = this_48
	else
		set LinkedListModule_next_3[LinkedListModule_last_3] = this_48
	endif
	set LinkedListModule_next_3[this_48] = 0
	set LinkedListModule_last_3 = this_48
endfunction

function construct_Path1 takes integer this_48 returns nothing
	call construct_Path1_LinkedListModule(this_48)
	call print("init path" + int_toString(LinkedListModule_size_3))
endfunction

function new_Path1 takes nothing returns integer
	local integer this_48 = alloc_Path1()
	call construct_Path1(this_48)
	return this_48
endfunction

function init_demo takes nothing returns boolean
	local integer clVar
	call new_Path1()
	call new_Path1()
	call new_Path1()
	call new_Path1()
	set clVar = alloc_Closure_63()
	call construct_CallbackSingle(clVar)
	call doAfter(1., clVar)
	set LinkedListModule_first_4 = 0
	set LinkedListModule_last_3 = 0
	set LinkedListModule_size_3 = 0
	call new_Iterator(false)
	call new_BackIterator_5(false)
	return true
endfunction

Where you can see values such as LinkedListModule_first_4 are set, but at the end of the package init, they are reset to 0.

I suspect this is the member initialization from the module:

   static thistype first = null
   static thistype last = null
   static int size = 0

Which happens at the end.

peq added a commit that referenced this issue May 16, 2018
@peq
Copy link
Collaborator

peq commented May 16, 2018

Should now be fixed: Module instance variables will be initialized before class variables.

@peq
Copy link
Collaborator

peq commented May 16, 2018

However, it is still possible to mess this up, by creating a class instance, before the class has been initialized. We should probably add a warning to avoid this.

@peq peq closed this as completed May 16, 2018
@PhoenixZeng
Copy link
Author

PhoenixZeng commented May 17, 2018

well . i test the new

package demo
import LinkedListModule
import ClosureTimers
import Execute
//(test1)
// public constant Path1 _top = new Path1()

init
    //(test2)
    // Path1 _top = new Path1()
    for i in Path1
        print(1.)
    doAfter(1)->
        for i in Path1
            print(2.)
    execute()->
        for i in Path1
            print(3.)

public class Path1
    use LinkedListModule
    construct()
        print("init path"+Path1.size.toString())
    //(test3)
    //static Path1 top = new Path1()
endpackage

package demo1
import demo
import ClosureTimers
import Execute
init
    for i in Path1
        print(4.)
    doAfter(1)->
        for i in Path1
            print(5.)
    execute()->
        for i in Path1
            print(6.)

@Frotty @peq
when open test1 and close other ,print: 1,3
when open test2 and close other ,print: 1,3
when open test3 and close other ,print: 4,6,2,5

it looks like should be used careful.
so why they

at the end of the package init, they are reset to 0.

@Frotty
Copy link
Member

Frotty commented May 17, 2018

Because package init happens top-down.
Simply moving your init block after the class will solve your problem.

@PhoenixZeng
Copy link
Author

PhoenixZeng commented May 17, 2018

change the package block position to
class - public const(test1) - init block
it worked ,good
(if position is class - init block - public const ,print 4,6,2,5. collide with the manual At the beginning of an init block you can assume that all global variables inside the current package are initialized.
thanks.

@Frotty
Copy link
Member

Frotty commented May 17, 2018

Yes, your second mistake was creating a class object before the class' definition.
E.g. this works fine:

package demo
import LinkedListModule
import ClosureTimers

init
    doAfter(1)->
        for i in Path1
            print(2.)

public class Path1
    use LinkedListModule
    construct()
        print("init path"+Path1.size.toString())

public constant Path1 _top = new Path1()

Just like

constant B = A
constant A = 1

A warning should be added.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants