iconic-lib/Queries [Path-based require/import + more]

iconic-lib/Queries

Queries is a shared library of global functions to query, import, and unpack content. It is part of Iconic Gaming’s set of code assets and systems available to the public, dubbed iconic-lib.

Uses

There are three main uses of this library:

  • Importing/requiring content in your game using a path
  • Pathless querying
  • Content unpacking from a module or instance

Import method

Usage example:

-- Similar to require(ReplicatedStorage:WaitForChild("Common"):WaitForChild("ModuleName"))
local MyModule = Import "ReplicatedStorage/Common/ModuleName"

 -- Similar to require(script.Foo.Bar)
local ChildModule = Import "./Foo/Bar"

-- Similar to require(script.Parent.Parent.Foo.Bar)
local ModuleFromAncestor = Import "../../Foo/Bar"

Import uses a path-based format (similar to what you have outside of Roblox) to import content and modules. It automatically required imported modules. Using the . keyword denotes that the path originates from the local directory, and .. is the parent directory. Otherwise, it defaults the parent directory to game.

This function does not require that you specify what script is calling it, it detects that on its own.

While this does remove some autofill, this is a great way to quickly import modules and content without a spam of Parent, FindFirstChild, or WaitForChild. It also is easier to read and edit. If you program outside of Roblox and are used to this format of importing data, this method is perfect for you.

Query method

Usage example:

-- In a script somewhere
local MyRandomNumber = Query("GetRandomNumber", 1, 100)
print(MyRandomNumber) -- Prints a number between 1 and 100
-- In a module somewhere, named _queryGetRandomNumber
-- In this example, it's located in ReplicatedStorage/Common/Queries/GetRandomNumber.lua
return function(Min : number, Max : number)
   return math.random(Min, Max)
end

-- If this query were done manually, you would have to call
-- require(ReplicatedStorage:WaitForChild("Common"):WaitForChild("Queries"):WaitForChild("GetRandomNumber")(Min, Max)

Query is a method that a.) finds a module named after what query is needed, and b.) calls that query module as a function.

Queries do not have to be located anywhere in particular, but they must have _query as a prefix in the name. For example, if you have a query named GetRandomNumber, then the module name must be named _queryGetRandomNumber. Naming two queries the same name may result in unexpected behavior.

If you want to create queries without having to require or path them, this method is great for you.

GetContents method

Usage example:

-- Get contents from module
local New, Value, Hydrate, Spring, Tween = GetContents(Fusion) {
   "New", "Value", "Hydrate", "Spring", "Tween"
}

-- Get modules from instance
local AllModulesDictionary = GetContents(script)

This usage example would be opposed to a typical way of doing things:

-- Old way of getting contents from module
local New = Fusion.New
local Value = Fusion.Value
local Hydrate = Fusion.Hydrate
local Spring = Fusion.Spring
local Tween = Fusion.Tween

-- Old way of getting modules from an instance
local AllModulesDictionary =  {}

for _, Module in script:GetChildren() do
   if Module:IsA("ModuleScript") then
      AllModulesDictionary[Module.Name] = require(Module)
   end
end

GetContents has two different behaviors:

  • If called with a module, it returns a function
    • This function takes an array of strings that represent keys in a dictionary
    • This content is returned as an unpacked tuple to the variables behind the function
  • If called with an instance, it returns a dictionary of required modules

This is just a simple way to reduce code without sacrificing readibility.

Installation

To use in your code, you can do one of the following.

Method 1 is requiring the module if it has not been initialized on the highest scope yet, or if you are not sure if it has:

local Import, Query, GetContents = require(Path.To.Queries).GetQueryMethods()

Method 2 assumes it has been required on any scope and is thus injected into _G:

local Import, Query, GetContents = _G.GetQueryMethods()

One of these two must be called in a high-level of each script using any three of these methods.
However, Import, Query, and GetContents also inject into _G themselves, meaning you can, for example, call _G.Import().

Get it now

The latest release is here:

Open to feedback

We want to refine this library to be more usable in large-scale projects. If you have feedback, let us know on our issues page.

5 Likes