[SOLVED] NoMethodError - Undefined method shadow_info

Hi guys !

I get an error in the Ruby console when I call this def styleswitch.
Can you help me solve this problem ? :slight_smile:

Error

Error: #<NoMethodError: undefined method `shadow_info=' for #<Sketchup::Model:0x0000015b40a09910>
Did you mean?  shadow_info>
[...] in `styleswitch'
[...] in `block in <module:MyPlugin>'

extension.rb

module MyPlugin
	module Data
		require 'sketchup.rb'
	end
		def self.styleswitch
		  style_wip = File.expand_path("_style_wip.style", File.dirname(__FILE__))
		  style_final = File.expand_path("_style_final.style", File.dirname(__FILE__))

		  styles = Sketchup.active_model.styles
		  shadow_info = Sketchup.active_model.shadow_info

		  if @style_now == style_wip
			styles.add_style(style_final, true)
			@style_now = style_final

			shadow_info["DisplayShadows"] = true
			shadow_info["Light"] = 50
			shadow_info["Dark"] = 75
			shadow_info["UseSunForAllShading"] = false
			shadow_info["DisplayOnAllFaces"] = true
			shadow_info["DisplayOnGroundPlane"] = true
			shadow_info["EdgesCastShadows"] = false
		  else
			styles.add_style(style_wip, true)
			@style_now = style_wip

			shadow_info["DisplayShadows"] = false
		  end

		  Sketchup.active_model.shadow_info = shadow_info
		end
	end
end

menu.rb

style_submenu = mymenu_menu.add_item("Style(s)") do
	MyPlugin::Data::styleswitch
end

The error message tells you exactly what the problem is.

Ie … Sketchup::Model objects do not have a shadow_info= method.

The backtrace information tells you the line number in the code, but you’ve truncated it above to [...].

I can see the bad statement as the last line of your styleswitch method …

		  Sketchup.active_model.shadow_info = shadow_info

… besides not allowed, this is unnecessary as you’ve already set individual attributes of the shadow info object belonging to the active model.


Aside. It is poor form to keep calling Sketchup.active_model within the same method. Make a local variable reference and reuse it. IE …

model = Sketchup.active_model

Are we seeing the menu.rb file as it really is?

local variables should not be defined at the top level ObjectSpace. They must be within your extension submodule.

1 Like

Thanks a lot @DanRathbun !

I followed your advice and it now works perfectly :slight_smile:

extension.rb

def self.styleswitch
    style_wip = File.expand_path("_style_wip.style", File.dirname(__FILE__))
    style_final = File.expand_path("_style_final.style", File.dirname(__FILE__))

    model = Sketchup.active_model
    styles = model.styles
    shadow_info = model.shadow_info

        if @style_now == style_wip
            styles.add_style(style_final, true)
            @style_now = style_final

            shadow_info["DisplayShadows"] = true
            shadow_info["Light"] = 50
            shadow_info["Dark"] = 75
            shadow_info["UseSunForAllShading"] = false
            shadow_info["DisplayOnAllFaces"] = true
            shadow_info["DisplayOnGroundPlane"] = true
            shadow_info["EdgesCastShadows"] = false
        else
            styles.add_style(style_wip, true)
            @style_now = style_wip

            shadow_info["DisplayShadows"] = false
        end
    end
end

Rather than the above, try to use:

def self.styleswitch
    style_wip = File.join(__dir__, '_style_wip.style')
    style_final = File.join(__dir__,'_style_final.style')

The reason is that File::expand_path is stupid. It is basically a dumb concatenation method that can result in erroneous non-existent paths. Therefore, it’s use is fragile.

Better to use the global __dir__() method with File::join.

EDIT (ADD): Not that File.join is any smarter, but it accepts the path parts in normal order.

1 Like