Global variable vs Field variable

BlitzMax Forums/BlitzMax Beginners Area/Global variable vs Field variable

pappavis(Posted 2008) [#1]
Whats up with Field-variables not acceable from Functions, however declaring it as Global then it is accesbale in a function?

Look at this TilesList-variable, it seems that after filling it with objects and then iterating through it in GetTileFromColRow reports no objects of type clsTegel found. Infact in other function (not shown) there were 494 clsTegel-objects added.

I was expecting some java/c# behaviour, in that a FIELD is just a public variable. Does a Global loos it value?

Type clsPlayfieldGrid
	Const CLASS_NAME:String = "clsPlayfieldGrid";
	Global AppInstance:clsMain1;
	Global TilesList:TList;
	Global _GRID_COLUMNS:Int;
	Global _GRID_ROWS:Int;
	Global _GridTileWidth:Int;
	Global _GridTileHeight:Int;

	Function Create:clsPlayfieldGrid() 
		Local grid1:clsPlayfieldGrid = New clsPlayfieldGrid;
		grid1.TilesList = New TList;
		grid1.SetGridTileHeight(32) ;
		grid1.SetGridTileWidth(32) ;
		
		grid1.InitGrid() ;
		
		Return grid1;
	End Function

	Function GetTileFromColRow:clsTegel(column:Int, row:Int) 
		Const METHOD_NAME:String = "GetTileFromColRow";
		Local tegel1:clsTegel = Null;
		
		Try
			'// doen iets.
			For tegel1 = EachIn Self.TilesList
				If(tegel1.Kol = column And tegel1.Ry = row) 
					Exit;
				EndIf
			Next
		Catch objErr1:Object
			Local strFout1:String = "  Fout in " + CLASS_NAME + "." + METHOD_NAME + "' --> " + objErr1.toString() ;
			Throw(strFout1) 
		EndTry		
		
		Return tegel1;
	End Function

EndType



tonyg(Posted 2008) [#2]
I am sure there's a simpler example you could have provided but, as it is, I might have missed the point.
- You're using 'self' in a function. Self refers to the instance of a type so is related to methods.
- TilesList is global to all the functions/methods within clsPlayFieldGrid so you can refer to it as TilesList
- The value of the globals is kept (static variable).
- Your code seems list globals and no fields. It also seems to be missing a number of methods referred to in your Create function.
Is this really the code you're using?


TaskMaster(Posted 2008) [#3]
Globals are variables that belong to the parent type. No matter how many objects you make from this parent type, there will always only be one of the global shared by all.

Fields are variables that belong to the individual types you create from the parent. Functions cannot access fields.

Functions belong to the parent type and only the ONE function ever exists. Functions can only access globals and cannot access fields because fields belong to the individual types you make, not the parent type.

Methods belong to the types you create from the parent. Methods can access fields and globals.

Hope this made sense?!?!


TomToad(Posted 2008) [#4]
Good tutorial on using types

http://www.blitzbasic.com/Community/posts.php?topic=59233#659777


Perturbatio(Posted 2008) [#5]
Yet another attempt to explain:

Fields and Methods are Local to the INSTANCE, Globals and Functions are globally accessible, even without any instance of the type.

Type TMyType
	Field X:Int = 0
	Global Y:Int = 0
	Method PrintX()
		X:+1
		print X
	End Method
	Function PrintY()
		Y:+1
		Print Y
	End Function
End Type

'TMyType.PrintX()'doesn't work
TMyType.PrintY()'works (Prints 1)

Local t1:TMyType = new TMyType
	t1.PrintX() ' prints 1
	t1.PrintY() ' prints 2
Local t2:TMyType = New TMyType
	t2.PrintX() ' prints 1
	t2.PrintY() ' prints 3


*Disclaimer: I just typed the code from my head, I haven't tested it since I don't have BMax at work.


pappavis(Posted 2008) [#6]

Globals are variables that belong to the parent type. No matter how many objects you make from this parent type, there will always only be one of the global shared by all.



Like statics?


Fields are variables that belong to the individual types you create from the parent. Functions cannot access fields.



Which is beyond me. Is there any (logical) reason why Fields cant be accessed by a function? That means that OOP-like GETter-functions isnt possible. How would one write this java-code in BlitzMax:

class clsPerson
{
  private string FirstName;

  public clsPerson()  //constructor
  {
    this.FirstName = null;
  }

  public void SetFirstName(string firstName)
  {
    this.FirstName = firstName;
  }

  public string GetFirstName()   // this getter impossible in BlitzMax?
  {
    return this.FirstName;
  }
}



How do one implement GetFirstName() in BlitzMax?


Azathoth(Posted 2008) [#7]
They're methods in that example, and firstname is a field.


pappavis(Posted 2008) [#8]
the reason for the clsPerson is to have invidual Person-classes.


No matter how many objects you make from this parent type, there will always only be one of the global shared by all.



As i understand it, using the blitzmax Global-type, implies that 200 personw will all share the name.



Its maybe time to read up on that tutorial.


ziggy(Posted 2008) [#9]
Like statics?

No. Like shared


Brucey(Posted 2008) [#10]
Here's an example of Java/BlitzMax for comparison, so you can see how both relate :

Some Java :
public class TWotsit {

	private int thing;
	private static String stuff;
	
	public int getThing() {
		return thing;
	}
	
	public static void setStuff(String newStuff) {
		stuff = newStuff;
	}
}

and some equivalent BlitzMax :
Type TWotsit

	Field thing:Int
	Global stuff:String
	
	Method getThing:Int()
		Return thing
	End Method
	
	Function setStuff(newStuff:String)
		stuff = newStuff
	End Function
	
End Type


so... a Global field of a Type is the same as a static field of a class. You can access it through all instances of objects of that Type, but it can also be accessed - like a static - without requiring an object instance.

Fields are the same as Java instance variables. That is, they require an object instance of the Type before they exist.
Methods are the same as Java instance methods.
Functions are the same as Java static methods.

HTH


TomToad(Posted 2008) [#11]
I originally wrote this last, but I thought it was such a good analogy, I moved it to the top of the post:

Imagine your an airplane mechanic working with other mechanics on a fleet of planes. There is a toolbox with tools for all of you to share. You've also bought your own personal tools which you keep with you.
If someone breaks a tool in the toolbox, then noone will be able to use that tool anymore. If one is replaced with a better tool, then everyone benefits from the upgrade.
However, noone can change a tool that is in your own possession, and any tool you change will not affect the tools that everyone else carries with them.

The tools in the toolbox are like Globals. The tools in your possession are like Fields. Functions are like rules on how you can handle the tools in the toolbox, however, those rules will not allow you to mess with someone else's personal tools. Example, "Rule #1: The socket wrenches are to be shared with everyone," Would not apply to someone's personal socket wrench, only the socket wrench in the toolbox.
Methods are like rules for handling your own personal tools, for example, "To remove this bolt, I'm going to use a box wrench instead of a socket wrench," Since you have access to the toolbox, you can use your own methods on those tools as well, as long as it doesn't conflict with the rules already set (Naming conflicts?)

This is what I originally wrote:
there is a difference between a type and an instance of a type. For example, Int is a type, but you cannot do Int = 5. You must first create an instance before you can assign a value, Score:Int = 5, Score is an instance.

Custom types are unique in that you can perform functions on the type itself, changing its behavior over all the instances of the types. It would be kind of like doing Int.Round = True so now .5 rounds to 1 instead of to 0.

Functions and Globals work on the Type itself, like the Int.Round example, and Fields and Methods work on an instance, Like Score:int = 5.

Since Fields are part of an instance of a Type, Functions will not work with them since no instance exists or being referenced.

Here's another way of looking at it.
When you create a type with the Type/End Type commands, a pool is created which contains your Globals. All instances of the type share this pool so changing the value in one will change the value in all. Since this pool is created at program start, your program can access it even when no instances exist.

When you create an instance of the type with the New command, a separate pool is created with the Fields that only that instance can see. No other instance can modify it without referencing the owning instance, and changing it will not affect other instances. Since this pool is owned by a particular instance, it is non-existent until an instance is created.

When you call a Method, a reference to the field pool for that instance is passed to the method, so the method can now access all the fields, and since there is only one Global pool reference, Methods can still have access to it. When you call a Function, there is no instance being used and therefore no reference to any Field pool is being passed.


Czar Flavius(Posted 2008) [#12]
This is getting too complicated.

Pappavis, I think the trouble stems from that you are confusing methods with functions

Type person
 Field name:String

 Method setname(newname:String)
  name = newname
 End Method

 Method getname:String()
  Return name
 End Method
End Type

Local aperson:person = New person
aperson.setname("Bob")
Print aperson.getname()