Python eval() Method in GD.Script

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By magnes3d

https://repl.it/@JonathanEversol/Variables-Dynamic-Variable-References-Working

There is a link to exactly what I need. And you can test it out for yourself, it does work, at least on Replit

hammer = “Gong”
hammer1 = [“Super Ninja”,“Juice”]

print(eval(“hammer”))
print(eval(“hammer1[0]”))
print(eval(“hammer1[1]”))

output1 - Gong
output2 - Super Ninja
output3 - Juice

Does anyone know what the equivalent to Pythons eval() in GDScript might be?

I have been trying to get this to work for some time now and I still cannot find a solution.
I have tried Expression.new() and str2var(), but both do not seem to work.

I get a 404 error with your link.

exuin | 2021-02-28 02:19

It is working now, I had the link set to private. I didn’t notice because I didn’t try it from a different account before I posted it and couldn’t notice without trying from a different account. Anyway it works now, my apologies.

magnes3d | 2021-02-28 15:21

:bust_in_silhouette: Reply From: exuin

Use the get function to get a property with a string. The property must not be local variable (declared inside a function). So, you can do

get("hammer")

You can also call this with an Expression. So you can do

expression.parse("get('hammer')")
expression.execute([], self)

str2var() doesn’t work because var is variant and not variable. Converting the string version of a string to a variant will just give you a string.

I wouldn’t recommend doing any of this though. It seems overly complicated. Is there a reason you need to use Strings for this?

You sir are a gentlemen and a Scholar.

magnes3d | 2021-02-28 15:27

I just read the rest of your comment, lol. Sorry about that. But I noticed you said that this seems overly complicated… I am curious why you would say that when you have almost no context for that assertion.

But perhaps it is overly complicated. I did try and simplify my question and it looks like you were able to answer it which I highly appreciate.

I tend to look at things in a different way when compared to other people, however I am always up for figuring out better ways to code things.

The reason I needed the above was so I could create an 2 Arrays. The arrays carry instructions that will be carried out in a Loop. One array carries a command, such as File_Open, Save-File and Quit Program. The other Array is the sister to this array. It holds the Short cut key commands for the first array.

By changing the arrays at the top Beginning of my code I can add additional buttons with additional Short cut commands. There are many different ways to code the same thing and make it happen, however I decided to use get to convert my second arrays strings into shortcuts instead of using Match.

Perhaps you can look at my Madness and give me some pointers.

I did manage to get it working the way I want. And I could expand what I wrote to include more buttons and more short cuts by just adding more to my Arrays. It is basically filling in the buttons and shortcuts for me so I don’t have to go through a bunch of steps to create them over and over.

Now if I did it the best and most efficient way possible… I don’t know.

Auto Filled Buttons and Shortcuts - Replit

extends Control   #         First_Program


var Program_Name = "Window's Master"
const UNTITLED = "Untitled"
var Current_file_Path = "Untitled"
onready var Editor = get_node("Editor_Window")

#Menu Buttons-------------------------------------------------------------------
onready var File_MenuButton = get_node("Dialog_Holder/HBoxContainer/File_MenuButton")
onready var Help_MenuButton = get_node("Dialog_Holder/HBoxContainer/Help_MenuButton")
var File_MenuButtons_Array = [     "New_File"     ,    "OpenFile"      , "SaveAs",      "Save"         ,      "Quit"      ]             #List of buttons to be added to File_Menu
var File_MenuButtons_Cuts  = [[78,"Cntrl","",""]  , [79,"Cntrl","",""] ,    ""   ,  [83,"Cntrl","",""] ,[81,"Cntrl","",""]]
var Help_MenuButtons_Array = ["Tutorial_Videos","About"]             #List of buttons to be added to File_Menu
var Help_MenuButtons_Cuts  = []
#Use Global Scope to find the correct KEY Value ie Scancode
#To Add Shortcut key Combos, Pass correct Scancode for first Digit [#####,"Cnrtl","Alt","Shift"]
#If there is no Shortcut for The button, Create an Empty string for its counter part 
#Example of Empty Slot [[78,"Cntrl","",""], "" ] ---> func Populate_Shortcuts(x,type)
#Menu Buttons-------------------------------------------------------------------


func _ready():
	Update_Windows_Title()
	OS.window_position = Vector2((OS.window_size.x/4), (OS.window_size.y/4)) # Centers the window on screen
	Populate_Menu_Buttons()   #Populates the Top Buttons


#File Operations ----------------------------------
#Read - 1
#Write - 2           - The file is created if it does not exist, and truncated if it does.
#Read_Write - 3      - Does not truncate the file.
#Write_Read - 7      - The file is created if it does not exist, and truncated if it does.
#File Operations ----------------------------------

#This function Opens a Selected File And Populates the Editor with its contents
func _on_OpenFile_Dialog_file_selected(path):
	Current_file_Path = path        #Stores the path of the file Opened
	var current_file = File.new()   #Creates a new file to open
	current_file.open(path, 1)      #Opens the File with READ permissions
	Editor.text = current_file.get_as_text()   #Fills  the Editor with the contents of the file
	current_file.close()            #Closes the File to prevent overflow issues
	Update_Windows_Title()

#This function Saves Contents of the editor as a .txt
func _on_SaveAs_Dialog_file_selected(path):
	Current_file_Path = path        #Stores the path of the file Opened
	var current_file = File.new()   #Creates a new file to open
	current_file.open(path, 2)      #Opens the File with WRITE permissions
	current_file.store_string(Editor.text)     #Fills the File with the Editors current contents
	current_file.close()            #Closes the File to prevent overflow issues
	Update_Windows_Title()

#This Updates the Windows Title
func Update_Windows_Title():
	OS.set_window_title(Program_Name + " - " + Current_file_Path)


#This Clears Editor and Starts a new File
func New_File():
	Current_file_Path = UNTITLED       #Stores the path of the file Opened
	Update_Windows_Title()
	Editor.text = ""

#Takes the Person to My YouTube channel
func Tutorial_Videos():
	OS.shell_open("https://www.youtube.com/channel/UCuTWaHsvhqTtUOIUkM0qLDQ")


func Save():
	if Current_file_Path == UNTITLED:
		$Dialog_Holder/SaveAs_Dialog.popup()   #Bring up the Save As Option
	else:
		_on_SaveAs_Dialog_file_selected(Current_file_Path)



#This Function Fills in the buttons for the Top Bar
func Populate_Menu_Buttons():
	for x in File_MenuButtons_Array:               #Get the File Buttons array
		var loc = File_MenuButtons_Array.find(x)   #Where we are at in Array
		File_MenuButton.get_popup().add_item(x)    #Add button to File_MenuButtons
		Populate_Shortcuts(loc,"File")             #Send Location in Array and which Array
	for x in Help_MenuButtons_Array:               #Get the Help Buttons array
		Help_MenuButton.get_popup().add_item(x)    #Add button to Help_MenuButtons
#Links the pressed button to _on_item_pressed Function
	File_MenuButton.get_popup().connect("id_pressed", self,"_on_item_pressed",["File"]) #connects File Buttons to Pressed
	Help_MenuButton.get_popup().connect("id_pressed", self,"_on_item_pressed",["Help"]) #connects Help Buttons to Pressed



#Pulls in the shortcut keys decided by Arrays at top.
#Key must be decided by Scan Code INT
#get() is used to convert arrays dynamically so Names of Arrays, Buttons, Dialogs are Critical
#Arrays Must be formatted Correctly. The arrays Generate the Buttons and the Shortcut Key Combos
func Populate_Shortcuts(x,type):
	var shortcutKEYS_array = type + "_MenuButtons_Cuts"   #Stores Correct Shortcut Array
	var Menubutton_array = type + "_MenuButton"           #Stores Correct Button Array
	var shortcut = ShortCut.new()                         #Starts process of adding a shortcut key
	var inputeventkey = InputEventKey.new()               #Starts process of capturing input event
	if get(shortcutKEYS_array)[x].empty() == false:       #If there is a Shortcut Combo for the buttton
		inputeventkey.set_scancode(get(shortcutKEYS_array)[x][0])  #Sets Shortcut Key using Global Scope
		if get(shortcutKEYS_array)[x][1] == "Cntrl" or get(shortcutKEYS_array)[x][2] == "Cntrl" or get(shortcutKEYS_array)[x][3] == "Cntrl": #Is there a Cntrl key picked?
			inputeventkey.control = true             #Adds Cntrl key to Shortcut Keybind
		if get(shortcutKEYS_array)[x][1] == "Alt" or get(shortcutKEYS_array)[x][2] == "Alt" or get(shortcutKEYS_array)[x][3] == "Alt":   #Is there a Alt key picked?
			inputeventkey.alt = true                 #Adds Alt key to Shortcut Keybind
		if get(shortcutKEYS_array)[x][1] == "Shift" or get(shortcutKEYS_array)[x][2] == "Shift" or get(shortcutKEYS_array)[x][3] == "Shift": #Is there a Shift key picked?
			inputeventkey.shift = true               #Adds Shift key to Shortcut Keybind
		shortcut.set_shortcut(inputeventkey)         #Stores Shortcut Combo selected in Array
		get(Menubutton_array).get_popup().set_item_shortcut(x, shortcut, true)  #Adds Shortcut Combo
	else:#Shortcut combo doesnt exist
		#print("No Shortcut Assigned")
		pass



#This Links the Button Presses to the Correct Dialog box or action
func _on_item_pressed(item_id,from):
	var object = get_node_or_null("Dialog_Holder/HBoxContainer/"+from+"_MenuButton") #Which Button Was Clicked
	var item = object.get_popup().get_item_text(item_id)    #What item was selected in that button
	var calling = get_node_or_null("Dialog_Holder/"+item+"_Dialog") #Store Selection here
	if calling != null: #If calling is a node
		calling.popup() #Open the Dialog for it
	elif self.has_method(item): #Is calling a Function
		call(item) #Run The Function
	else:   #Something Went wrong
		print("No such Node or Method exists")

#Created a Quit Function for The Quit button in File Menu
func Quit():
	get_tree().quit()

magnes3d | 2021-03-02 02:52

Well, the reason I said it seemed overly complicated was because I couldn’t really see a need to parse text in order to get data from an array when you could just write code to do that.

exuin | 2021-03-02 03:47