Problems getting a value from self

Hello.
What Im doing: Im using self with metatables to get a tool from a table that is defined after a function is used.
What Im trying to do: In the module, I need to get this tool to connect a function to a event.
Problem/Issue: I can’t use self outside a function with : because it returns as a unknown global.
----------------------------------------
My question is: how would I get the tool to connect the event?

Function that sets the table:
_Tool is a table defined at the start of the module
image

How Im getting the tool:
image

What I want to do but errors:
image
----------------

Click here for more details

The reason for why I want to make these connections is:
In the module I have this property:
image
ActEvent: Is a BindeableEvent instance created when the module starts.
In the Connection: I want to make ActEvent:Fire() so in the scripts I can just make object.Activated:Connect()…

Any help is appreciated!

I’m not 100% sure what you’re trying to do here, but if you need to make connections associated with your object you should do that inside your constructor.

I already tried to make the connections inside the .new constructor but no results

Are you able to provide for us more of the module?

self can be used inside of . function members, too. You would just need to pass self as the first argument. It’s best to use : if the function isn’t static, though.

Maybe we can help you with setting up the connections in your module inside the constructor.

So, the .new constructor will create a new table for the tool instance specified in the argument #1 of the function.
—> This table contains various functions/properties, located in the _Tool table that I used in the setmetatable().
→ I want to make a event in this table: .Activated, where I declared this in this variable:
image
→ The solution I found to make this event works is using BindeableEvents:
image
Im firing this(and some others) event when a function in the _Tool table runs…
But what I want too is: This event be compatible with the default .Activated tool method of roblox, so the solution I found is:
image
However, as like I did in other module I made, Im trying to connect this event inside the module without any scope, and as you see in the screenshot above, Im using self.Tool to get the tool, and then connect the event: but self doesnt works as like this and this is my problem.

So, I was wondering: Is there a way to I get the tool and connect this event in a different way, or how could I make this “self” works?

What error have you received when trying to connect the event inside the constructor? Because you cannot use self globally. Are you trying to detect the module/self’s Activated event from a different script, but nothing is happening when setting up the connections inside the constructor?

Well, when I tried to connect the event in the constructor I got no errors, but also when trying to use the event in another script it did not works. I tried using the toolObject itself:

local toolObject = {}
setmetatable(toolObject, _Tool)
toolObject.Tool = tool

toolObject.Tool.Activated:Connect(function() ActEvent:Fire() end)

return toolObject

Maybe I did something wrong?

Can you send the entire module and its usage? Your screenshots are very limited.

I excluded some not important stuff, but heres the (resumed) module:

local ToolAPI = {}
ToolAPI.__index = ToolAPI
--[[=<:>=]]--
local _Tool = {}
_Tool.__index = _Tool

local ActEvent = Instance.new("BindableEvent")

function ToolAPI.new(tool: Tool)
	local toolObject = {}
	setmetatable(toolObject, _Tool)
	toolObject.Tool = tool
    toolObject.Tool.Activated:Connect(function() ActEvent:Fire() end)

	return toolObject
end


function _Tool:Activate()
	self.Tool:Activate()
	ActEvent:Fire()
end

_Tool.Activated = ActEvent.Event

return ToolAPI

Let me know if you need more information

How are you detecting the event fire in the other script?

Im using the .Activated event/variable defined in the _Tool table.

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local API = require(ReplicatedStorage:WaitForChild("ToolAPI"))
local tool = API.new(script.Parent)

tool.Activated:Connect(function()
  print("Activated") --> Works when I use the module function :Activate, but
   --doesnt works detecting with the default .Activated event using what I said or using the connection inside the constructor
end)

image

Is your Tool’s ManualActivationOnly property set to true? Because I copied your module and script, including setting up the connection inside the constructor function, and it works for me. But when I enabled ManualActivationOnly, it stopped working. It also stopped working with RequiresHandle enabled when there’s no handle.

1 Like

ManualActivationOnly is set to false.
Did you make the connection inside the constructor and did you you activated it just by clicking with the default roblox .Activated?

Also RequiresHandle was on, but I turned it to off and still not working. Im just using a empty tool.

Yes, I set up the Tool.Activated event listener inside the constructor, and I fired the BindableEvent with it.

function ToolAPI.new(tool: Tool)
    local self = setmetatable({}, Tool) -- Tool is _Tool for you.
    self.Tool = tool

    self.Tool.Activated:Connect(function() -- or just `tool.Activated`.
        activate:Fire() -- ActEvent:Fire() for you.
    end)

    return self
end

“Activated” is outputted from the script using this module.
This didn’t work for me when I enabled those two properties I named, though. I am using an empty Tool, as well.

Uhh, it works now. Thank you.
But I did’nt understand, whats the main difference between my code and this one you used? Could please explain?

My Previous code:

local toolObject = {}
setmetatable(toolObject, _Tool)
toolObject.Tool = tool
	
toolObject.Tool.Activated:Connect(function() ActEvent:Fire() end)
	
return toolObject

Your code:

local self = setmetatable({}, _Tool)
self.Tool = tool

self.Tool.Activated:Connect(function() ActEvent:Fire() end)
	
return self

Functionality wise, there’s no difference. Maybe it is because you disabled the RequiresHandle property and then set up the event listener inside the constructor?

Yah, probably. I had already tested without the “RequiresHandle” and with the event listener in the constructor and didnt works, thats weird.

Anyways, thank you!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.