ID:2128084
 
Not a bug
BYOND Version:510
Operating System:Linux
Web Browser:Chrome 51.0.2704.106
Applies to:DM Language
Status: Not a bug

This is not a bug. It may be an incorrect use of syntax or a limitation in the software. For further discussion on the matter, please consult the BYOND forums.
Tested on BYOND 510.1345 and 510.1346.

Descriptive Problem Summary:
While world.vars does not compile, world:vars does, returning null on read.
This is also the case for all vars present on /datum.

Numbered Steps to Reproduce Problem:
use world:vars somewhere

Code Snippet (if applicable) to Reproduce Problem:
/world/New()
world.log << isnull(world:vars) // 1
world.log << isnull(world:tag) // 1
world.log << isnull(world:type) // 1
world.log << isnull(world:parent_type) // 1


Expected Results: Either world:vars would runtime, or world.vars would compile and return meaningful results

Actual Results: world:vars does not runtime, returning null; world.vars does not compile.

Does the problem occur:
Every time? Or how often? Every time
In other games? N/A
In other user accounts? Yes
On other computers? Yes

When does the problem NOT occur? Unknown

Did the problem NOT occur in any earlier versions? If so, what was the last version that worked? Unknown

Workarounds: None known

This appears to go further than just datum; the following types all have vars that are accessible on world:

/datum (vars, tag, type, parent_type)
/list (len)
/atom (loc, x, alpha, icon_state)
/file (cd, eof, dir)
/client (authenticate, computer_id)
/mob (client)


I suspect all vars present on these types are accessible on world, but I'm not sure; I've only tested those in brackets after each type.

Edit: This goes even further than that; that was only what the compiler would let me do:

/datum
var/foo

/proc/getFoo(datum/D)
return D.foo

/world/New()
world.log << isnull(getFoo(world)) // 1


Essentially, any var lookup for a var world doesn't have should runtime, but it just returns null instead.

Double edit:

This is two bugs in one.

First, that var lookups on world return null instead of runtiming if the var does not exist, as shown above in my first edit.

Second, that the compiler allows the colon operator to compile regardless of the type of the variable if the var being accessed is present on any of /datum, /list, /atom, /file, /client, or /mob:

var/foo = 5
world.log << foo:len // Cannot read 5.len
In response to GinjaNinja32
GinjaNinja32 wrote:
Second, that the compiler allows the colon operator to compile regardless of the type of the variable if the var being accessed is present on any of /datum, /list, /atom, /file, /client, or /mob:

I'm positive this is intended behavior on the part of the colon operator. If the variable exists anywhere - no matter what namespace or object it's attached to, it'll compile, especially since you've created the foo variable without a type. The only issue here is that a runtime does not occur when dealing with world. The colon operator does absolutely no type-checking during compile. (I could totally be wrong.)
Lummox JR resolved issue (Not a bug)
In response to Super Saiyan X
Super Saiyan X wrote:
GinjaNinja32 wrote:
Second, that the compiler allows the colon operator to compile regardless of the type of the variable if the var being accessed is present on any of /datum, /list, /atom, /file, /client, or /mob:

I'm positive this is intended behavior on the part of the colon operator. If the variable exists anywhere - no matter what namespace or object it's attached to, it'll compile, especially since you've created the foo variable without a type. The only issue here is that a runtime does not occur when dealing with world. The colon operator does absolutely no type-checking during compile. (I could totally be wrong.)

Then why does M:len in the following compile, despite M:bar erroring?

It checks that the var is present on at least one subtype of the variable's type, except where the var is present on /datum, /list, /atom, /file, /client, /mob, in which case it entirely ignores the variable's type.

/mob/var/foo
/obj/var/bar

/world/New()
var/mob/M = new

var/f = M:foo // this is OK
var/c = M:len // this is... OK(!) despite len being a list var, not a mob one
var/b = M:bar // error: M/:/bar: undefined var


Lummox JR wrote:
Lummox JR resolved issue (Not a bug)

There are two issues here, neither of which make any sense for DM/DD to allow; I'm not sure how they can be "intended". If they're infeasible to fix, sure, but that doesn't make it "not a bug".

A post detailing why would be appreciated :)
In response to GinjaNinja32
GinjaNinja32 wrote:
Super Saiyan X wrote:
GinjaNinja32 wrote:
Second, that the compiler allows the colon operator to compile regardless of the type of the variable if the var being accessed is present on any of /datum, /list, /atom, /file, /client, or /mob:

I'm positive this is intended behavior on the part of the colon operator. If the variable exists anywhere - no matter what namespace or object it's attached to, it'll compile, especially since you've created the foo variable without a type. The only issue here is that a runtime does not occur when dealing with world. The colon operator does absolutely no type-checking during compile. (I could totally be wrong.)

Then why does M:len in the following compile, despite M:bar erroring?

It checks that the var is present on at least one subtype of the variable's type, except where the var is present on /datum, /list, /atom, /file, /client, /mob, in which case it entirely ignores the variable's type.

> /mob/var/foo
> /obj/var/bar
>
> /world/New()
> var/mob/M = new
>
> var/f = M:foo // this is OK
> var/c = M:len // this is... OK(!) despite len being a list var, not a mob one
> var/b = M:bar // error: M/:/bar: undefined var
>

if you typecast M, it check for things in the subtypes. In your other example, the variable is not typecast so it checks the entire scope of variables. I think len is included because DM is weird and it's not a datumic variable.
mob.len working without an error would be a separate issue; I'm not sure why that doesn't produce an error. I suppose that could be considered a bug.

The world object returns null without an error for all vars it doesn't have, and does not have a var lookup for user-defined vars. Calling this a bug is a bit much, IMO; the territory being explored here is mostly undefined, and there's no reason to "fix" it because nobody would do this under realistic circumstances.
In response to Super Saiyan X
Super Saiyan X wrote:
GinjaNinja32 wrote:
...

if you typecast M, it check for things in the subtypes. In your other example, the variable is not typecast so it checks the entire scope of variables. I think len is included because DM is weird and it's not a datumic variable.

DM is very weird, then; it's not just non-datum variables that are usable like this; everything that's pre-defined on datum/list/atom/file/client/mob is:

/world/New()
var/list/L = list()

var/m = L:mob // client
var/c = L:client // mob
var/cd = L:cd // file
var/i = L:icon_state // atom
var/b = L:bar // error: L/:/bar: undefined var


Edit: The above, minus the M:bar line, does *not* runtime on execution; the same nonexistent-vars-return-null seems to be true of lists as well as world.