Global "create" function

"If you write it twice a day, then just make a ModuleScript for it. That’s part of the point of them. Code reuse! "

Only to end up writing “require(module)” twice a day or more at the top of every script.

@Shagmeister and every other person who has suggested a workaround: Yes, we know we can use modules! Yes, we know we can reuse code! Yes, we know we can replace the keyword Instance with our own variation! The whole purpose of this feature request is to save us the trouble of continually repeating that over and over and over for something that should already be part of the API in the first place!

@Who: It would make sense to parent the part last. That solves all cases where you’d need to know the part’s properties as soon as it’s parented to the workspace. I’ve never run into any issues with CFrame/Position/Anchored though. If you can provide a repro for that, then ROBLOX could take that into consideration, but until then, there’s nothing to verify that other than “I think”. And it really doesn’t even matter if it doesn’t set the property order correctly in some edge case. If it doesn’t work for your edge case then just set the properties manually. This feature isn’t going to hurt you, so I don’t see why you’d be complaining.

[quote] “you can’t set properties in a determinable order.”

There are only a few cases where the order matters. The only ones that I can think of are FormFactor and Shape needing to be set before size, but ROBLOX can determine that behind the scenes and set them in the correct order. That isn’t an appropriate reason to trash the feature request – it’s not a problem at all.

“because you can’t have nil values”
All Object values default to nil. It doesn’t matter if you can’t set it to nil from Instance.new – it’s already nil to begin with. [/quote]

My point is that a key/value table isn’t a good way to define the properties of an object, for the reasons mentioned. The syntax is neat, but the unpredictable behavior and other issues that emerge from it are not acceptable for an official API. It’s the kind of thing you’d see in a hack. That’s really all it is in the first place; a syntactical hack.

You already linked to the thread, but here’s a great quote from it that summarizes my thoughts:

CSG is less predictable than everything yet it’s still a feature. BillboardGui.StudsOffset doesn’t even work, yet is still an official property. The animation editor is bug-riddled and Animation.KeyframeReached doesn’t fire correctly yet animations are still an official implementation.

The point I’m trying to make is that guideline is not all-powerful. It’s certainly important to ensure that official changes to the API are stable and work how you’d expect them to, but in the cases where the unpredictability is immeasurable and the usefulness greatly outweighs the downsides (if any), it’s perfectly reasonable to add something to the API. Disregarding it because instead of 100% predictable it’s 99.9% predictable is just being picky for the sake of being picky – OCD cleanliness-like. Adding this certainly won’t break anything, so there are 0 downsides to implementing it, and the only issues you’ll face with using the new syntax are a couple edge cases which can be reported to ROBLOX and then fixed.

I’ll notion towards CSG again. It was intentionally implemented despite having known issues (a lot more issues than an overloaded table parameter might have). It was implemented because of its usefulness. So what if it doesn’t work for edge cases (or anything outside of grid-aligned parts)? Even with its limitations, it’s still one of the most helpful things in the world. Just because you have a feeling that there will be a couple issues with this doesn’t disqualify it from feature status, and doesn’t make all of the people who would benefit from this unimportant.

RbxUtility has a Create function. ROBLOX doesn’t just put random things in that library – Create is one of five functions provided by that library, four of which have been made into features (SelectTerrainRegion, EncodeJSON, DecodeJSON, and CreateSignal (although there is no function to create a LuaSignal, ROBLOX created BindableEvents/Functions)). It’s about time the final one got made into a real feature.

In oxcool1’s (now Voidacity’s) script builder, the serverside sandbox adds a special feature.
If you do object{properties} (just call a roblox instance with a table) it’ll (try to) set all the properties from the table.
This would completely work with Instance.new"Part" and Instance.new"Part"{properties}
You could just have at the top of your script something like: require(assetId)()
Which then turns your current env in a sandboxed one that allows a lot of tricks.
(This trick, monitoring all the things automaticly, stop most crash code, …)

Of course that’s just being difficult.
Instance.new(ClassName,Properties) is nice.

@Anaminus
We could always have Instance.nil, which can be inserted in the properties table
to say “this has to be set to nil”, like the RbxUtlity.CreateSignal has CreateSignal.E for events.

“You could just have at the top of your script something like: require(assetId)()”

[quote=Echo]
@Shagmeister and every other person who has suggested a workaround: Yes, we know we can use modules! Yes, we know we can reuse code! Yes, we know we can replace the keyword Instance with our own variation! The whole purpose of this feature request is to save us the trouble of continually repeating that over and over and over for something that should already be part of the API in the first place!
[/quote]

"We could always have Instance.nil, which can be inserted in the properties table
to say “this has to be set to nil”, like the RbxUtlity.CreateSignal has CreateSignal.E for events. "

[quote=Echo]
All Object values default to nil. It doesn’t matter if you can’t set it to nil from Instance.new – it’s already nil to begin with.
[/quote]

[quote] “You could just have at the top of your script something like: require(assetId)()”

[quote=Echo]
@Shagmeister and every other person who has suggested a workaround: Yes, we know we can use modules! Yes, we know we can reuse code! Yes, we know we can replace the keyword Instance with our own variation! The whole purpose of this feature request is to save us the trouble of continually repeating that over and over and over for something that should already be part of the API in the first place!
[/quote]

[/quote]
Just another workaround that hasn’t been suggested, could be fun to use.
(Sandboxing can have lots of debugging purposes instead of restriction of stuff)
(I once built an unrestricted sandbox, where you could whitelist properties, and when set from the client,
they would replicate to the server and be set there. Very handy for FilteringEnabled.
And yes, I made a working clientside Instance.new for FilteringEnabled with filters)

[quote]
"We could always have Instance.nil, which can be inserted in the properties table
to say “this has to be set to nil”, like the RbxUtlity.CreateSignal has CreateSignal.E for events. "

[quote=Echo]
All Object values default to nil. It doesn’t matter if you can’t set it to nil from Instance.new – it’s already nil to begin with.
[/quote]
[/quote]
I know that, and I agree, just giving a counter argument for Anaminus’ thing.

I’ve been thinking about a set method that accepts two arguments, a property and a value. The method returns the object again.

 obj:set(property, value) -- returns obj 

So we can do something like this:

local part = Instance.new("Part", workspace)
	:set("Name", "SomePart")
	:set("BrickColor", BrickColor.new("Really black"))
	:set("FormFactor", "Custom")
	:set("Size", Vector3.new(5,5,5))

Which is a possible solution to this issue and is quite neat as well.

And then I win in the end :swag:

local np = Instance.new("Part")
np.FormFactor = "Custom"; np.Size = Vector3.new(0.2, 0.2, 0.2)
np.CanCollide = false; np.Transparency = 1; np.Anchored = true;
np.TopSurface = 0; np.BottomSurface = 0; np.Name = "AmazingPart"

Wow only 4 lines! How did that happen??!?

Actually I’m just sharing my part in clean code and while this approach is not super readable, it still works out really well in the end. I used to use table settings myself, but this serves to be more handy for some reason.

[quote] And then I win in the end :swag:

local np = Instance.new("Part")
np.FormFactor = "Custom"; np.Size = Vector3.new(0.2, 0.2, 0.2)
np.CanCollide = false; np.Transparency = 1; np.Anchored = true;
np.TopSurface = 0; np.BottomSurface = 0; np.Name = "AmazingPart"

Wow only 4 lines! How did that happen??!?

Actually I’m just sharing my part in clean code and while this approach is not super readable, it still works out really well in the end. I used to use table settings myself, but this serves to be more handy for some reason. [/quote]

you might like this syntax

local part = Instance.new("Part")
part.Anchored, part.CanCollide = true, false
part.CFrame, part.Size = otherCFrame, Vector3.new(4, 5, 6)
part.Name, part.Parent = "ya", workspace

I find myself using a create function from time to time, mostly for UI stuff since there’s a lot of property setting in some cases.

Not that it should be used, but I wanted to make a create function with a priority list, so I modified Ethan’s function.

[quote]
you might like this syntax

local part = Instance.new("Part") part.Anchored, part.CanCollide = true, false part.CFrame, part.Size = otherCFrame, Vector3.new(4, 5, 6) part.Name, part.Parent = "ya", workspace [/quote]

That’s interesting, I’ve never seen the tuple set used along with values in a table, this actually works?

[quote]
you might like this syntax

local part = Instance.new("Part") part.Anchored, part.CanCollide = true, false part.CFrame, part.Size = otherCFrame, Vector3.new(4, 5, 6) part.Name, part.Parent = "ya", workspace [/quote]

That’s interesting, I’ve never seen the tuple set used along with values in a table, this actually works?[/quote]

Yep!

[quote]
you might like this syntax

local part = Instance.new("Part") part.Anchored, part.CanCollide = true, false part.CFrame, part.Size = otherCFrame, Vector3.new(4, 5, 6) part.Name, part.Parent = "ya", workspace [/quote]

That’s interesting, I’ve never seen the tuple set used along with values in a table, this actually works?[/quote]

The code can read it but humans can’t

If your excuse for something being unpredictable is that something else is unpredictable, then you’re an idiot.

We use CSG despite unpredictability because THERE ARE NO ALTERNATIVES.

THERE ARE CLEAR ALTERNATIVES HERE.

[quote] [quote=“WhoBloxedWho” post=172863]
you might like this syntax

local part = Instance.new("Part") part.Anchored, part.CanCollide = true, false part.CFrame, part.Size = otherCFrame, Vector3.new(4, 5, 6) part.Name, part.Parent = "ya", workspace [/quote]

That’s interesting, I’ve never seen the tuple set used along with values in a table, this actually works?[/quote]

The code can read it but humans can’t[/quote]

Am I not human or am I missing something? lol.

[quote]
you might like this syntax

local part = Instance.new("Part") part.Anchored, part.CanCollide = true, false part.CFrame, part.Size = otherCFrame, Vector3.new(4, 5, 6) part.Name, part.Parent = "ya", workspace [/quote]

That’s interesting, I’ve never seen the tuple set used along with values in a table, this actually works?[/quote]

How about this?

local func="sin"
local arg=5
(func=="sin" and math.sin or math.cos)(arg)

or something like this:
local table={}
local a=false
table[a and "a" or "b"]=4

I simply don’t see any reason this create function is any useful.

You still have to set each property manually, except with the new create() function you have to define them in a dictionary table. That’s the same potential number of lines wrapped in a table. Then, that create function has to manually unwrap that table using a loop. If you want the same finesse as without the create() function, then the create() function has to act like a priorietyqueue for the properties. BULK BULK BULK.

Just because you sweep the lines of code under the rug of someone else’s API doesn’t make the code any more efficient in any sense. There is nothing wrong with having more lines of code.

[quote] I simply don’t see any reason this create function is any useful.

You still have to set each property manually, except with the new create() function you have to define them in a dictionary table. That’s the same potential number of lines wrapped in a table. Then, that create function has to manually unwrap that table using a loop. If you want the same finesse as without the create() function, then the create() function has to act like a priorietyqueue for the properties. BULK BULK BULK.

Just because you sweep the lines of code under the rug of someone else’s API doesn’t make the code any more efficient in any sense. There is nothing wrong with having more lines of code. [/quote]

The goal is to make object construction easier to read and write. When you’re creating something like guis where you have a hierarchy it’ can take a while to understand the order unless you tab it so that children are tabbed further than their parents. With this style of creating an object you’re able to instance many objects without worrying about variable names, parents, and readability.

[quote] I simply don’t see any reason this create function is any useful.

You still have to set each property manually, except with the new create() function you have to define them in a dictionary table. That’s the same potential number of lines wrapped in a table. [/quote]

The main benefit isn’t that it saves lines (because it doesn’t) – it’s that it saves us from having to type out the variable name (or even create one) time after time after time.

306 characters:

local bulletTrail = Instance.new("Part")
bulletTrail.TopSurface = "Smooth"
bulletTrail.BottomSurface = "Smooth"
bulletTrail.FormFactor = "Custom"
bulletTrail.Size = Vector3.new(0.2,0.2,distance/2)
bulletTrail.CFrame = CFrame.new(start, end) * CFrame.new(0,0,-distance/2)
game.Debris:AddItem(bulletTrail ,1)

236 characters:

game.Debris:AddItem(Instance.new("Part", {
TopSurface = "Smooth";
BottomSurface = "Smooth";
FormFactor = "Custom";
Size = Vector3.new(0,0,distance/2);
CFrame = CFrame.new(start, end) * CFrame.new(0,0,-distance/2)
Parent = workspace;
}))

The second one doesn’t require a temporary variable and can be minimized since the properties are in a table. Who are you to decide what clean code is? You are unable to speak for everyone – this not being clean is an opinion, just as it being clean is an opinion. It ultimately comes down to how many people think it’s clean. As Anaminus said though, this has been discussed to death. A lot of people prefer code to be structured like this, and that’s not something you can argue about.

Boo hoo it uses a loop – this isn’t something that gets executed ninety-thousand times a second, so the performance impact is negligible. If you don’t like it, then don’t use it. Nobody is forcing you to use it.

You’re very out-of-touch with ROBLOX developers. The majority of us (think of everyone who isn’t a member of the forums) don’t use an external editor, and you’re still creating a temporary variable that you’ll discard as soon as you’re done with it.