Println(what); - "what" argument datatype

I’m making a debug tool in which I can print out values on a gui every frame, and I want to be able to input any type of value—much like how println/print works.

After looking at the reference page, I noticed how it said that the datatype of the argument(s) is called “what”, and I don’t know exactly what this means. Below it states that the “what” refers to various other datatypes (i.e. Object, String, float, char, boolean, etc.), but I was curious as to how exactly println does this.

What I originally thought is that it does something like this, by overloading the function:

void println(String... p) { [...] }
void println(float... p) { [...] }
void println(char... p) { [...] }
void println(boolean... p) { [...] }

But I then realized that this is impossibly the way that it’s programmed, because not only can you input user-defined objects (which would not work using this method), but you can also input various different datatypes like such:

println("text", 1.0, 'a', false, [...]);

Is it possible to replicate a system that can accept arguments like these so that I could implement this into my debugging tool?

Thanks!

Update:
I looked a little more and was able to find more in-depth documentation for println—in the PApplet github page. I have a lot more to look into haha

What isn’t a datatype.

Example of data types: float, int, bool etc.

Println is a function which accepts parameters and uses console log to write to the console.

Anatomy of a function

Void name ( parameter){

}
Void is the return type and this one specifies that there is nothing to return. It can however have a data type instead of void, in which case you must use return to return the data type specified.

The parameter field can be empty or it can contain one or more parameter.

In a class you can only have one instance of a function unless the parameters are different also called overloading.

So I cannot have two functions named doSomething();

But I can do this

Void doSomething( int a){

}

Void doSomething(float a){

}

Also changing void at the start does not count as overloading, only amending or adding parameters counts as overloading.

Overloading shouldn’t be confused with overriding which is a bit more advanced as you have to know about class inheritance first.

1 Like

So the println() function works by having multiple functions with different parameters, as described in the docs you linked to.
For a different approach, I found this when googling: https://stackoverflow.com/questions/2914695/how-can-you-write-a-function-that-accepts-multiple-types/2914730

The resulting code work in processing:

void setup() {
   printing('a');
   printing("yourstring");
   printing(123);
}

<T> void printing(T stuff){
  println(stuff);
}

In the link above it is also explained how to make this work with arrays n stuff. I hope that helps!

2 Likes

what is just the name of the parameter in the reference (print what). It’s more a word play really. An example for what is 3 or “Hello”.

So indeed different data type can be used.

I am not sure about your example of various different datatypes.

But here is an example with an example function that accepts different parameters; in fact they are different functions with the same name but different parameters.


void setup() {
  size(700, 770);
}

void draw() {
  background(0); 

  float b1=0.34; 
  myText(b1); 

  String b2="Hallo";
  myText(b2);

  int b3=4; 
  myText(b3);

  myText(4, 7, 9, 12, 17);
}

//--------------------------------------------------------------

void myText(float a) {
  text(a, 100, 100);
}

void myText(int a) {
  text(a, 100, 200);
}

void myText(String a) {
  text(a, 100, 300);
}

void myText(int... a) {
  int x=100; 
  for (int i1 : a) { 
    text(i1, x, 400);
    x+=100;
  }
}
//

It is possible to design a function to accept user-defined objects with the typical overloading just by using the general datatype Object. The reference describes the arguments for a list of variables as an Object []. I think this just means it is defined as a varying length list of variables, like in @Chrisir example just the data type is of type Object.

The real challenge is how the function should figure out what is the appropriate way to display the user-defined types. The println function doesn’t really display the value of the complex data types given to it

2 Likes

I tried this below using try/catch expression.

With Object... a in the header of the function.

It would be more elegant if we had something like :

switch(typeOfObject(o1)) {
   case STRING_:
   ...
   break; 
   case INT_:
   ...
   break; 
   case FLOAT_:
   ...
   break; 
   .....
}//switch

true to an extent.

It shows PVector and also arrays quite well.

There is also printArray().

Sometimes I write my own println() functions though.

Chrisir

void setup() {
  size(700, 770);
}

void draw() {
  background(0); 

  float b1=0.34; 
  myText(100, b1); 

  String b2="Hallo";
  myText( 200, b2);

  int b3=4; 
  myText(300, b3);

  myText(400, 4, 7, 9, 12, 17 );

  myText(500, 4, "7", 9.872, 12, "17", "Hello", 19 );
}

//--------------------------------------------------------------

void myText(float y1_, 
  Object... a ) {

  int x=100;

  for (Object o1 : a) {

    try {
      text((String) o1, x, y1_);
    } 
    catch(Exception e) {
      try {
        text((float) o1, x, y1_);
      }
      catch(Exception e2) {
        text((int) o1, x, y1_);
      }
    }
    x+=100;
  }//for
}
//
2 Likes

Nice! I really like this idea for debugging, building a general-purpose println for complex data types. I just wonder if there would be any way to display all the variables in any class, sort of like printArray. I don’t know if its possible to access these variables without knowing the names, but it would be really helpful not to have to write new code in the printing function for each data type.

processing itself has a debugger in its newer versions though

Thank you, everybody for your help!
I think Chrisir was pretty spot on for what I was looking for, so for my tool I’ll probably do something similar to that.

1 Like

You might want to take a look at the java.lang.reflect docs, specifically the Field class.
There is also a tutorial: https://docs.oracle.com/javase/tutorial/reflect/class/classMembers.html

Here is a sample function that will print all the variables of an object:

void debugPrint(Object o){
	System.out.println(o.getClass().getName() + "{");
	
	for(Field f:o.getClass().getDeclaredFields())
		try{
			f.setAccessible(true);
			System.out.printf(
				"\t%-10s %s %s\t= %s\n",
				Modifier.toString(f.getModifiers()),
				f.getType().getSimpleName(),
				f.getName(),
				f.get(o)
			);
		}
		catch(IllegalAccessException e){
			System.out.println(e);
		}
	
	System.out.println("}");
}

The output can get a bit messy, but it prints the type of the object modifiers, variable type, variable name and value.

2 Likes