What does do .... end mean

Hi, I’ve seen in some scripts where people do:

do
  --Code here
end

Is this necessary for anything or does it have any difference from without the do function or?

5 Likes

It’s completely useless. I wouldn’t wasting script space with it.

3 Likes

its usually a loop with numbers, such as

for i = 1, 5 do
--do something 5 times
end

never seen it alone though,

2 Likes

This is with for loops, where is does have a purpose, lol. Using do alone (which is what the OP is asking about) does work, but it runs completely normally as if it wasn’t there.

do
    print("Hi")
end

Output: Hi
print("Hi")

Output: Hi

Exactly the same results. Using do by itself is useless.

2 Likes

do blocks are usually used in one of 3 cases.

  • for loops
  • while loops
  • Limiting a variable’s scope

ex.

for i = 1, 10 do
	print(i)
end

while task.wait(1) do
	print("infinite!")
end

Now for the one you probably want, do block by itself (not completely by itself?).

do
	-- code
end

When limiting the scope of a variable is useful, a do block is used, ex:

local getId
do
	local lastId = 0
	getId = function()
		lastId += 1

		return lastId
	end
end

Here, lastId is unneeded in any other part of the code, limiting it’s scope is helpful. This also sets the getId to a function that needs that variable which is why it’s defined in the same scope (inside the same do block).


Hope that made sense, feel free to ask questions if something is confusing you.

12 Likes

to add on to what @msix29 has described the use of a do ... end block, its also useful to organize code in a way.

local variable
do
    local complex_math = math.random(1,10) / 10
    if complex_math > 0.5 then
        variable = complex_math
    end
end

This would be an example of limiting the scope of the complex_math variable, but it can also be useful in the code editor, as a do ... end block acts like its use in other forms, such as for loops, where you can collapse all the code in a do block to hide something that you may not need to constantly see, especially if you tend to scroll around you code alot, this is useful in making the scroll take less time.

Limiting variables isnt just useful to keep the variable scope clean, but it can also be useful to limit memory to a degree, as variables when they exit scope, as long as no other references to said variable is in the code roblox’s engine will garbage collect the variable. (Below is an example where a variable in a do block is still referenced, and thus not garbage collected)

local GoodSignal = require(script.GoodSignal) -- A module that is luau implementation of roblox signal objects, such as BindableEvent.

local signal = GoodSignal.new()
do
    local complex_math = math.random(1,10) / 10
    signal:Connect(function ()
        print(complex_math)
    end)
end

RunService.Heartbeat:Connect(function (step)
    signal:Fire()
end)

In this example, we use GoodSignal, a module of an efficient roblox signal interface in luau (aka not using BindableEvents and friends), and we have the variable complex_math in the do block, along with a connection on our created signal, then outside the do block we fire the signal every frame (we wouldnt even need to do that, as as long as the signal object we created is in scope, the variable complex_math will be in memory. This is another example of organizing our scope though, because our code outside the do block cant reference complex_math, but we can still use it in code inside the do block, and it can still stay in memory for “indefinite” as long as signal exists.

I at least like using do blocks in my code on rare occasions… but it definitely isnt needed to use or even understand

3 Likes

Simply put is used to create a block of code that can be treated as a single unit. It is used in conjunction with control flow statements.

1 Like

Almost think of it as an if then statement that just checks “true” so it always fires, then as you know everything local in the statement can’t go out of the code block, so just apply the same rules there,

1 Like

Tell me you don’t know scoping in Lua without telling me you don’t know scoping in Lua. Could’ve at least looked it up first before making the reply and it tells you the use case right here lol

https://www.lua.org/pil/4.2.html

Edit: Oh and if you wonder why it matters to isolate locals in the first place, it’s because there’s a limit!

So in addition to organizing your code, it lets you recycle locals and keep you far away enough from the register limit. Otherwise, your code would fail to compile.

image

6 Likes

I’m mostly self taught, so even after seven years of messing with Roblox, there’s still a lot of gaps in my knowledge. My knowledge on scoping is… patchy. Thank you for teaching me lmfao.

2 Likes

There’s only one case where I have actually used a do/end construct, and that is to limit the scope of a variable. When dealing with module scripts and initializing them, sometimes a lot of temporary variables can be created. By encapsulating the code in a do/end construct, those variables are limited to the inside of the do/end and do not pollute the module script’s global namespace.

This can be important because this reduces the possibility of having a naming conflict and helps to reduce bugs. It also makes it easier to come up with new variable names because unique names that are descriptive tend to be hard to come up with and allows variable names to be reused in different contexts. It’s considered bad practice (and a code smell) to define a local variable that’s the same name as a global. In other languages, like C/C++, depending on the compiler, a warning will be thrown if it’s encountered. I know for a fact that gcc and clang will do this.

Hope this helps.

1 Like

Yeah, I know about for and while loops using do but I’m trying to figure out what exactly it does by itself.

1 Like

I knew it was the same results but was wondering if there was a specific purpose for it.

1 Like

I suppose you could use the same variable name multiple times if you put it in a do block

1 Like

I thought the limit was 500 lol. Just a question about limits, is this per script or the entire game? I’m guessing per script but better make sure.

1 Like

Yup. If a variable isn’t needed by all the script but needed for only one thing, it’s better to limit it’s scope. I personally never ran into cases where using a do block was needed, maybe it’s just how I structure my code, I like keeping files small and clean.

end is only syntax for closing a scope. Nothing much but that.

You need to close the scope every time you indent once or twice via either of:

  • while [condition] do
  • for [iterations] do
  • if [condition] do
  • function [name]()
  • do

However, repeat uses until [condition] to close unlike everything else.

It is used to assign a variable that is used temporarily in a scope. do, as a keyword, defines a scope, as well as a function and an if ... then.

local value1 = true do

--here the variable value1 will always be true
print(value1)

end

--the value does not exist outside of the scope
print(value1) --> nil

This has been said many times throughout this thread, but this is probably the simplest explanation.

You mean this right?

do
local value1 = true
--here the variable value1 will always be true
print(value1)

end

--the value does not exist outside of the scope
print(value1) --> nil
1 Like

No. local value do works just fine. I’ve used it many times before.