Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't use a variable as a dice roll #1

Closed
Morgul opened this issue Nov 5, 2015 · 2 comments
Closed

Can't use a variable as a dice roll #1

Morgul opened this issue Nov 5, 2015 · 2 comments
Labels

Comments

@Morgul
Copy link
Owner

Morgul commented Nov 5, 2015

Let's assume I have the following scope:

{
    Weapon: {
        Damage: '1d6'
    }
}

I cannot do the following: 'Weapon.Damage' + 1; Weapon.Damage evaluates to a string, and I get '1d61' out.

@Morgul Morgul added the bug label Nov 5, 2015
@Morgul
Copy link
Owner Author

Morgul commented Dec 28, 2018

See, this is a tricky one. While I get why I wanted this, I either need to make Variables smarter (i.e. make them try to evaluate themselves) or I have to make Operations smarter, and try to evaluate Variables.

I think I like the first one better; part of being a 'variable' could simply be, "we must resolve ourself to the correct basic type on evaluation'.

@Morgul
Copy link
Owner Author

Morgul commented Dec 29, 2018

Second tricky part: How to prevent recursion? Do we not pass in the scope, do we unset our key from the scope, or do we attempt to detect recursion, and throw an error?

Here's how I break those down:

  1. Don't pass in outer scope
    • Pro: Simplest option; we only ever evaluate one level of nesting.
    • Con: Doesn't allow for Weapon.Damage to equal 1d6 + 'Abilities.StrMod', an easy to imagine use case.
  2. Unset our key from the scope
    • Pro: It immediately breaks any recursion, while still allowing for nesting.
    • Pro: Covers all reasonable use cases, while disallowing clearly abusive ones.
    • Con: It is both difficult and slow to emulate _.unset.
    • Con: Requires cloning the scope; the deeper nested, the more clones of the scope are made. (If scope is a large object, this could run us out of memory.)
  3. Detect recursion, and throw an error
    1. Detect by name reference
      • Pro: Detects blatantly abusive case, without modifying anything
      • Con: Easily defeated, since it doesn't detect cycles.
      • Con: Difficult to implement.
    2. Store current depth in scope, limit to a maximum value
      • Pro: Usage agnostic, simply limits maximum parsing depth.
      • Pro: Trivial Implementation.
      • Con: Modifies scope; we shouldn't touch a user's object.
      • Con: 'leaks' maximum depth.
      • Con: Does not directly address recursion, so it might not be obvious what's wrong.
    3. Store current depth in Expression, limit to a maximum value
      • Pro: Usage agnostic, simply limits maximum parsing depth.
      • Pro: Trivial Implementation.
      • Con: Does not directly address recursion, so it might not be obvious what's wrong.

At this point, after working all of that out, I'm opting for 3.3, since it seems the easiest to implement, and seems a reasonable guard.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant