How to "print" a variable (aka the newbiest of newbie questions)

This may be the most newbie question of all.

Is there a way to get programmatic access to whatever magic ROOT does when you just enter an expression and hit ENTER?

Example: I’m messing around with a YAML parser library. This is what it looks like:

#include <yaml.h>
yaml_parser_t parser;
yaml_event_t event;
FILE *file = fopen("/home/jayson/.config/joystick_to_teensy.yaml", "rb");
yaml_parser_initialize(&parser);
yaml_parser_set_input_file(&parser, file);
yaml_parser_parse(&parser, &event);
while (event.type != YAML_NO_EVENT) {
	printf("%d\n", event.type);
	yaml_parser_parse(&parser, &event);
}
fclose(file);

Note the printf in the middle of the for loop. It just prints out boring old numbers:

(boring old numbers)
1
3
9
6
9
6
9
6
9
6
9
6
6
6
6
6
6
6
6
10
6
9
6
7
6
6
6
6
8
6
7
6
6
6
6
8
10
10
10
10
10
4
2

However, if I step through this loop by hand and inspect the value of event.type by evaluating it on the REPL, I get all this lovely extra data:

root [0] #include <yaml.h>
root [1] yaml_parser_t parser;
root [2] yaml_event_t event;
root [3] FILE *file = fopen("/home/jayson/.config/joystick_to_teensy.yaml", "rb");
root [4] yaml_parser_initialize(&parser);
root [5] yaml_parser_set_input_file(&parser, file);
root [6] yaml_parser_parse(&parser, &event);
root [7] event.type
(yaml_event_type_t) (YAML_STREAM_START_EVENT) : (unsigned int) 1
root [8] yaml_parser_parse(&parser, &event)
(int) 1
root [9] event.type
(yaml_event_type_t) (YAML_DOCUMENT_START_EVENT) : (unsigned int) 3
root [10] yaml_parser_parse(&parser, &event)
(int) 1
root [11] event.type
(yaml_event_type_t) (YAML_MAPPING_START_EVENT) : (unsigned int) 9
root [12] yaml_parser_parse(&parser, &event)
(int) 1
root [13] event.type
(yaml_event_type_t) (YAML_SCALAR_EVENT) : (unsigned int) 6
root [14] yaml_parser_parse(&parser, &event)
(int) 1
root [15] event.type
(yaml_event_type_t) (YAML_MAPPING_START_EVENT) : (unsigned int) 9
root [16]

Is there a command that would allow me to print out that super cool introspection-aware information from inside my for loop?

I do not have the yaml.h file nor your data file. So I cannot try your example. But I guess what you are looking for is what is printed when you do something like:

root [1] int i=1
(int) 1
root [2] auto h = new TH1F()
(TH1F *) 0x7fe133762110
root [3] 

ie the two lines:

(int) 1
(TH1F *) 0x7fe133762110

I am not sure what the cling interpreter is doing at that point and if there is a generic way to get the same in a compiled program. May be @vvassilev can help you.

Are you using cling or ROOT?

In cling you might be able to do something like:

[cling] #include <cling/Interpreter/Interpreter.h>
[cling] ...
[cling] for(...) { gCling->echo("event.type"); }

I’m using ROOT.

I was under the impression that ROOT is the new CLING, sort of like CLING was the new CINT.

I see a couple of different Interpreter.h files kicking around in the ROOT source code, quite a few references to gCling, and even a few places where gCling->echo gets called, but nothing that I can seem to use from the ROOT prompt.

Thanks for responding.

yaml.h is coming from the “libyaml” library, which comes from package libyaml-dev on Debian Linux (+ derivatives).

The YAML file itself is something of little to no consequence, just something to feed to the parser. It looks like this:

joysticks:
  8Bitdo NES30 Pro:
    NES:
      EV_KEY:
        BTN_A: 0x01
        BTN_B: 0x02
        BTN_SELECT: 0x04
        BTN_START: 0x08
      EV_ABS:
        ABS_HAT0X: [0, 0x40, 0, 0x80]
        ABS_HAT0Y: [0, 0x10, 0, 0x20]

The same thing can be demonstrated with no external libraries like this:

typedef enum sammich_type_e {
	CHICKEN_SAMMICH,
	HAM_SAMMICH,
	GRILLED_CHEESE_SAMMICH,
	KNUCKLE_SAMMICH
} sammich_type_t;

sammich_type_t sammy = HAM_SAMMICH;

If you then enter sammy on the prompt, you get:

root [16] sammy
(sammich_type_t) (HAM_SAMMICH) : (unsigned int) 1

As opposed to what you get if you use printf:

root [17] printf("%d\n", sammy);
1

So what I’m ultimately looking for is something that will convince ROOT to print out the more informative (sammich_type_t) (HAM_SAMMICH) : (unsigned int) 1.

if you use root that might be able to help:

std::unique_ptr<TInterpreterValue> v = gInterpreter->MakeInterpreterValue();
gInterpreter->Evaluate("event.type", *v);
v->ToString();

C purists, C++ purists, look away…

#include <yaml.h>
std::unique_ptr<TInterpreterValue> v = gInterpreter->MakeInterpreterValue();
yaml_parser_t parser;
yaml_event_t event;
FILE *file = fopen("/home/jayson/.config/joystick_to_teensy.yaml", "rb");
yaml_parser_initialize(&parser);
yaml_parser_set_input_file(&parser, file);
yaml_parser_parse(&parser, &event);
while (event.type != YAML_NO_EVENT) {
	gInterpreter->Evaluate("event.type", *v);
	cout << v->ToString() << endl;
	yaml_parser_parse(&parser, &event);
}
fclose(file);

Output:

(yaml_event_type_t) (YAML_STREAM_START_EVENT) : (unsigned int) 1

(yaml_event_type_t) (YAML_DOCUMENT_START_EVENT) : (unsigned int) 3

(yaml_event_type_t) (YAML_MAPPING_START_EVENT) : (unsigned int) 9

(yaml_event_type_t) (YAML_SCALAR_EVENT) : (unsigned int) 6

(yaml_event_type_t) (YAML_MAPPING_START_EVENT) : (unsigned int) 9

(yaml_event_type_t) (YAML_SCALAR_EVENT) : (unsigned int) 6

(yaml_event_type_t) (YAML_MAPPING_START_EVENT) : (unsigned int) 9

(yaml_event_type_t) (YAML_SCALAR_EVENT) : (unsigned int) 6

(yaml_event_type_t) (YAML_MAPPING_START_EVENT) : (unsigned int) 9

(yaml_event_type_t) (YAML_SCALAR_EVENT) : (unsigned int) 6

(yaml_event_type_t) (YAML_MAPPING_START_EVENT) : (unsigned int) 9

(yaml_event_type_t) (YAML_SCALAR_EVENT) : (unsigned int) 6

(yaml_event_type_t) (YAML_SCALAR_EVENT) : (unsigned int) 6

(yaml_event_type_t) (YAML_SCALAR_EVENT) : (unsigned int) 6

(yaml_event_type_t) (YAML_SCALAR_EVENT) : (unsigned int) 6

(yaml_event_type_t) (YAML_SCALAR_EVENT) : (unsigned int) 6

(yaml_event_type_t) (YAML_SCALAR_EVENT) : (unsigned int) 6

(yaml_event_type_t) (YAML_SCALAR_EVENT) : (unsigned int) 6

(yaml_event_type_t) (YAML_SCALAR_EVENT) : (unsigned int) 6

(yaml_event_type_t) (YAML_MAPPING_END_EVENT) : (unsigned int) 10

(yaml_event_type_t) (YAML_SCALAR_EVENT) : (unsigned int) 6

(yaml_event_type_t) (YAML_MAPPING_START_EVENT) : (unsigned int) 9

(yaml_event_type_t) (YAML_SCALAR_EVENT) : (unsigned int) 6

(yaml_event_type_t) (YAML_SEQUENCE_START_EVENT) : (unsigned int) 7

(yaml_event_type_t) (YAML_SCALAR_EVENT) : (unsigned int) 6

(yaml_event_type_t) (YAML_SCALAR_EVENT) : (unsigned int) 6

(yaml_event_type_t) (YAML_SCALAR_EVENT) : (unsigned int) 6

(yaml_event_type_t) (YAML_SCALAR_EVENT) : (unsigned int) 6

(yaml_event_type_t) (YAML_SEQUENCE_END_EVENT) : (unsigned int) 8

(yaml_event_type_t) (YAML_SCALAR_EVENT) : (unsigned int) 6

(yaml_event_type_t) (YAML_SEQUENCE_START_EVENT) : (unsigned int) 7

(yaml_event_type_t) (YAML_SCALAR_EVENT) : (unsigned int) 6

(yaml_event_type_t) (YAML_SCALAR_EVENT) : (unsigned int) 6

(yaml_event_type_t) (YAML_SCALAR_EVENT) : (unsigned int) 6

(yaml_event_type_t) (YAML_SCALAR_EVENT) : (unsigned int) 6

(yaml_event_type_t) (YAML_SEQUENCE_END_EVENT) : (unsigned int) 8

(yaml_event_type_t) (YAML_MAPPING_END_EVENT) : (unsigned int) 10

(yaml_event_type_t) (YAML_MAPPING_END_EVENT) : (unsigned int) 10

(yaml_event_type_t) (YAML_MAPPING_END_EVENT) : (unsigned int) 10

(yaml_event_type_t) (YAML_MAPPING_END_EVENT) : (unsigned int) 10

(yaml_event_type_t) (YAML_MAPPING_END_EVENT) : (unsigned int) 10

(yaml_event_type_t) (YAML_DOCUMENT_END_EVENT) : (unsigned int) 4

(yaml_event_type_t) (YAML_STREAM_END_EVENT) : (unsigned int) 2

That works beautifully! Thank you!

1 Like