About Monkey 2 › Forums › Monkey 2 Development › Static method call without New = Error
This topic contains 5 replies, has 4 voices, and was last updated by
abakobo
1 year, 3 months ago.
-
AuthorPosts
-
January 6, 2018 at 7:35 am #12692
Should this work?
Monkey1234567891011121314151617181920Namespace test#Import "<std>"Using std..Const TEST := Test.Count()Function Main()Print "Main"EndClass Test FinalGlobal List := New List<Test>Function Count:Int()Print "Test.Count is called"Return List.Count()EndEndI get “Attempt to invoke method on null instance” using the itch version of v1.1.08.
January 6, 2018 at 9:08 am #12697This had changed some months ago. I think it’s to avoid calling uninitialized fields..
January 6, 2018 at 9:30 pm #12717This is because the compiler can’t work out the dependancies involved correctly.
It does a pretty good job of simpler stuff like:
Monkey123Global Z:=X*YGlobal Y:=X*2Global X:=10…but with your example above, TEST is dependant upon Test.List (so Test.List must be inited first) via the Test.Count function (actually, via a function call *within* the Test.Count function), but the compiler isn’t smart enough to work out dependancies via function calls like this – and probably never will be I’m afraid so I’m not quite sure what the solution is! For now you’ll have to work around it…
This had changed some months ago. I think it’s to avoid calling uninitialized fields..
This is unrelated really – it used to be that you could call a method on a null object as long as the method never read/wrote any fields, but no longer. But here, we’re talking about a function, not a method.
January 7, 2018 at 12:58 am #12718So this use to work?
In Java its doable, I’m not bothered either way just was trying out nerobot’s preferences code:
Monkey1Const Prefs:=Preferences.Get( AppDir()+"prefs.json" )January 7, 2018 at 5:25 pm #12737It worked for me. But this code is technically equivalent to above one. So it can produce null pointer.
As a solution for prefs, we can initialize _ptefs field right inside of Get () if it is null.
Consts initialization is a weak side of monkey2, that may cause errors, so that it’s important to have related remarks in docs.
(Waiting for a developer that can bring dependency checking.)
January 8, 2018 at 9:09 am #12749This is unrelated really
sorry, have been reading the code too fast..
Consts initialization is a weak side of monkey2
Things have been corrected already, what should be mentioned? To me it’s logical that the code would not work even thought “List” is global (I would have called it “LIST”..). But “List” can be declared in head declarations BEFORE “TEST”. It would have the same effect as it global anyway.
Do you mean that the fact we can’t make some Forward declaration should be documented?
An example to illustrate my logic (here there’s no class instance but the global is declared in head declarations):Monkey1234567891011121314151617181920Namespace test#Import "<std>"Using std..Global LIST := New List<Test> ' invert those two lines and it will failConst TEST := Test.Count() 'invert those two and it will failFunction Main()Print "Main"EndClass Test FinalFunction Count:Int()Print "Test.Count is called"Return LIST.Count()EndEndAbout Classes documentation, there’s is a lack about Classes functions. They are not mentioned at all and thus it’s not mentioned that Classes’ functions may not use a class field (“Error : Field ‘xxxx’ cannot be accessed without an instance.”)
As for a practical working example, wouldn’t a function pointer be more “dynamic”. Here there is a class instance which is Const (and containg only global “fields”)..
Is all this expected behaviour (note the Const Class has it’s field modified, I suppose it’s the reference that is Const)?Monkey1234567891011121314151617181920212223242526272829303132333435363738394041424344Namespace test#Import "<std>"Using std..Const TESTER:=New Test()Const TESTCOUNT_FUNC := TESTER.CountConst TESTCOUNT_INT:=TESTCOUNT_FUNC()Function Main()Print "Main"Print "TESTCOUNT_INT: "+TESTCOUNT_INTPrint "TESTCOUNT_FUNC(): "+TESTCOUNT_FUNC()Print ""TESTER.AddStuff()TESTER.AddStuff()Print ""Print "TESTCOUNT_INT: "+TESTCOUNT_INT + " -> has not changed"Print "TESTCOUNT_FUNC(): "+TESTCOUNT_FUNC()Print "direct acces to Test.LIST without Instance: "+Test.LIST.Count()EndClass Test FinalGlobal LIST := New List<Test>Method AddStuff()Print "Test.AddStuff is called"Local t:=New Test()LIST.Add(t)EndFunction Count:Int()Print "Test.Count is called"Return LIST.Count()EndEnd -
AuthorPosts
You must be logged in to reply to this topic.