About NameError: wrong constant name
-
Hi , I was wondering something in a code.
Today , I tested a code in SketchUp 2014 and I got an error about NameError: wrong constant name , const_get , block in add_callbacks in the line 270. But , older versions of SketchUp can be used.Error; #<NameError; wrong constant name ["HTMLRenderer"]> C;/Users/Windows8/AppData/Roaming/SketchUp/SketchUp 2014/SketchUp/Plugins/Exporter/gui.rb;270;in `const_get' C;/Users/Windows8/AppData/Roaming/SketchUp/SketchUp 2014/SketchUp/Plugins/ Exporter /gui.rb;270;in `block in add_callbacks' -e;1;in `call'
Here's an original code.
Line 270 : #renderer = Kernel.const_get(format_string).new(result_hash['round_dimensions'].to_s == "on" ? true : false)# This takes the name of a class and creates a new instance of it. format_string = result_hash['format'].to_s renderer = Kernel.const_get(format_string).new(result_hash['round_dimensions'].to_s == "on" ? true ; false)
After that I revised from (format_string) to be (HTMLRenderer.to_s)
There's no error pop-up when opening SketchUp , but it doesn't show a report text in a Web Dialog.
Meanwhile , it's surprise to work in SU8-2013. I don't know how to make a code correctly in a bracket > (HTMLRenderer.to_s)renderer = Kernel.const_get(HTMLRenderer.to_s).new(result_hash['round_dimensions'].to_s == "on" ? true ; false)
-
Hi pingpink.
I think the problem is coming from how 'Class.to_s' works, and what namespace the HTMLRenderer class is defined in.
The original code is looking for a Class that is inside the Kernel namespace, using a String so that the Class used can be changed on-the-fly - the end result of the lookup would be something like "Kernel::MyClass".
The problem with your change is likely one of two things...-
The class HTMLRenderer is NOT in the Kernel namespace - possibly just plain-old 'HTMLRenderer' in the main 'global' namespace. In this case "Kernel" would be the wrong place to look for the constant.
-
The class IS inside Kernel. In this case "const_get(HTMLRenderer.to_s)" would actually return the full name of the Class, including any 'superclasses' - which would be "Kernel::HTMLRenderer".
But 'Kernel' is already specified as the receiver of the 'const_get' method - leaving us looking for the constant "Kernel::Kernel::HTMLRenderer". As there's no module "Kernel::Kernel", this won't be found, and you get a NameError.
Whichever it is, the code is more complex than it needs to be...
The original code is using 'const_get' so that it can choose a class at run-time - 'format string' is choosing what kind of object to make. If you now always want an instance of HTMLRenderer, there is no need to look up the constant this way, you can just write...renderer = Kernel;;HTMLRenderer.new(...etc...)
NB) This assumes that the HTLMRenderer class really is inside the namespace of Kernel. If not, the bit before the '::' may need to be different; or possibly it is not needed at all if the class is in the global namespace.
-
-
Stay out of the
Kernel
namespace module. It is mixed intoObject
, and therefore mixed into EVERYONE's classes and modules and objects!If you want to use a string classname (from a hash,) to access the actual class, then use the global
eval()
method:rdims = @options['round_dimensions'] == 'on' ? true : false eval("@options['engine_class']").new( rdims )
-
Thank you kindly, Trogluddite and Dan Rathbun
I understand from reading your advice. Maybe, it's about class reference.
These are the 3 ways I tried to do, I can't find the problem in a code yet.renderer = Kernel;;HTMLRendererP.new(result_hash['round_dimensions'].to_s == "on" ? true ; false) puts "[ToolWebUIP.add_callbacks('handle_run')] renderer; #{renderer}"
Error :
[ToolWebUIP.add_callbacks('handle_run')] parts: #PartListP:0xd9a0f28
Error: #<NameError: uninitialized constant Kernel::HTMLRendererP>
C:/Users/Windows8/AppData/Roaming/SketchUp/SketchUp 2014/SketchUp/Plugins/CurtainWall/Export/CW_Panel/gui.rb:271:inblock in add_callbacks' -e:1:in
call'format_string = result_hash['format'].to_s renderer = @options['round_dimensions'] == 'on' ? true ; false eval("@options['format_string']").new( renderer ) puts "[ToolWebUIP.add_callbacks('handle_run')] renderer; #{renderer}"
Error :
[ToolWebUIP.add_callbacks('handle_run')] parts: #PartListP:0xded0ed8
**Error: #<NoMethodError: undefined method[]' for nil:NilClass>** C:/Users/Windows8/AppData/Roaming/SketchUp/SketchUp 2014/SketchUp/Plugins/CurtainWall/Export/CW_Panel/gui.rb:275:in
block in add_callbacks'
-e:1:in `call'format_string = result_hash['format'].to_s renderer = Kernel.const_get(format_string).new(result_hash['round_dimensions'].to_s == "on" ? true ; false) puts "[ToolWebUIP.add_callbacks('handle_run')] renderer; #{renderer}"
Error :
[ToolWebUIP.add_callbacks('handle_run')] parts: #PartListP:0xddb8f00
Error: #<NameError: wrong constant name ["HTMLRendererP"]>
C:/Users/Windows8/AppData/Roaming/SketchUp/SketchUp 2014/SketchUp/Plugins/CurtainWall/Export/CW_Panel/gui.rb:270:inconst_get' C:/Users/Windows8/AppData/Roaming/SketchUp/SketchUp 2014/SketchUp/Plugins/CurtainWall/Export/CW_Panel/gui.rb:270:in
block in add_callbacks'
-e:1:in `call'
Advertisement