Inputbox in module not showing when called

I have two scripts, Test1 and Test2. In Test2, I require 'Test1' as follows:

require_relative './Script Test/Test1'

module ScriptTest2

		extend self

	def test2
		ScriptTest1.test1
	end

  def toolbar_maker(toolbar_name)
    toolbar = UI::Toolbar.new toolbar_name
    toolbar_photo = "a_picture.jpg"
  
    #Specify the command to be run
    cmd = UI::Command.new(toolbar_name) {
      test2
    }
    cmd.small_icon = toolbar_photo
    cmd.large_icon = toolbar_photo
    cmd.tooltip = toolbar_name + ' Toolbars'
    cmd.status_bar_text = toolbar_nam
    toolbar = toolbar.add_item cmd
    toolbar.show
  end
  toolbar_maker("Test")
end

And this is Test1:

module ScriptTest1

	extend self

	def test1
		prompts = 'Test1:'
		values = 'test'
		final = inputbox prompts, values, 'Test Inputbox...'
		UI.messagebox(final)
	end
end

Folder structure is as follows:

Script Test.rbz

Script Test

Test1.rb

Test2.rb

I loaded it to sketchup using the extension manager, and the toolbar has loaded…all well and good.
But when I click the button, nothing happens.
There are no load errors when I Close and reopen SketchUp either…

Why?
:thinking::question:

P.S.
Apologies for the terrible coding too :face_with_hand_over_mouth:

UI.messagebox and UI.inputbox can fail silently.
This is why you should never use UI.messagebox to debug code.
Output inspection values to the console instead.

For the UI.inputbox method, prompts, defaults and list (of choices) are all array arguments, so try …

final = inputbox [prompts], [values], 'Test Inputbox...'

… or more clearly …

  def test1
    prompts = ['Test1:']
    values = ['test']
    final = inputbox( prompts, values, 'Test Inputbox...' )
    puts final.inspect
  end

Yup…thats the (stupid) solution solved :sob:, but that means the problem I’m actually having confuses me more…done a bit more testing, and if I call a second method outside of the module, rather than within, as follows:

require_relative './Script Test/Test1'
require 'path/to/ToolbarCreator.rb'

module ScriptTest2

  extend self

  def test2
    ScriptTest1.test1
  end
end

ToolbarCreator.toolbar_maker('Draws Columns', ScriptTest2.test2)

and ToolbarCreator.rb is as follows:

module ToolbarCreator
  def self.toolbar_maker(tool_name, does_this)
    toolbar = UI::Toolbar.new "Test"
    # This toolbar icon runs the inputbox required to Test"
    toolbar_photo2 = "a _photo.jpg"
  
    cmd = UI::Command.new(tool_name) {
      does_this
    }
    cmd.small_icon = toolbar_photo2
    cmd.large_icon = toolbar_photo2
    cmd.tooltip = tool_name
    cmd.status_bar_text = tool_name
    toolbar = toolbar.add_item cmd
    toolbar.show
  end
end

Now, I know it will work, if I do it as i did in the previous example…but I want a module that I can call, to create new toolbars for everything!! And the previous example gets the following error:
C:/path/to/Script Test/Test1.rb:12:in `test1': undefined method `inputbox' for ScriptTest1:Module (NoMethodError)
from C:/path/to/Script Test.rb:11:in `test2'
from C:/path/to/Script Test.rb:13:in `<module:ScriptTest2>'
from C:/path/to/Script Test.rb:6:in `<main>'
[Finished in 0.2s with exit code 1]

aaaaand that isnt explained away by some missing braces :unamused:

Learn to read the error messages …

… tells you:

  • The error occured at line 12
  • within file "C:/path/to/Script Test/Test1.rb"
  • in method "test1"
  • that the error was a NoMethodError
  • because module ScriptTest1 does not have a method defined that is named "inputbox"

Doing this …

ToolbarCreator.toolbar_maker('Draws Columns', ScriptTest2.test2)

… will execute ScriptTest2.test2 method and return it’s result as the 2nd parameter to the ToolbarCreator.toolbar_maker method call.

What you need to do it get a reference to the ScriptTest2.test2 method object like so …

does_this = ScriptTest2.method(:test2)
ToolbarCreator.toolbar_maker('Draws Columns', does_this)

… and then inside ToolbarCreator.toolbar_maker method …

    cmd = UI::Command.new(tool_name) {
      does_this.call()
    }

To see what methods that the Method class has, refer to …

1 Like

Thanks for that…it works perfectly now…just need to keep slogging away at learning ruby and eventually I could potentially be helping add answers to this site :smile:

2 Likes

We have a bunch of SketchUp extension examples on GitHub: https://github.com/SketchUp/sketchup-ruby-api-tutorials

It does assume you know Ruby already, but I just wanted to highlight it.