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

this scoping issue #16

Open
freeman42x opened this issue Jul 13, 2015 · 5 comments
Open

this scoping issue #16

freeman42x opened this issue Jul 13, 2015 · 5 comments
Labels

Comments

@freeman42x
Copy link

It seems that in CodeCombat the functions operating on this usually work when called from outside functions or inside functions, and usually they do not work when nested deeper into code.

For example:

(dotimes [n 1000]
  (let [enemy (.findNearestEnemy this)]
    (.say this "Is there an enemy?")
    (if enemy
      (do
        (.say this "An enemy spotted!")
        (if (< (.distanceTo this enemy) 5)
          (.attack this enemy)
          (.shield this)))
      (.moveXY this 40 34))))

will print Is there an enemy? but never An enemy spotted! even though it becomes true.

This might have something to do with the visibility of this / JavaScript scoping rules.

Since I can only log using .say and .say needs this I can't even log this to figure out if this happens to be nil there.

@freeman42x
Copy link
Author

If I use:

(dotimes [n 1000]
  (let [enemy (.findNearestEnemy this)]
    (.say this "Is there an enemy?")
    (if enemy
      (.say this "An enemy spotted!")
      (.moveXY this 40 34))))

it will display correctly "An enemy spotted!" when condition becomes true.

So it seems like the do is doing something to this, pardon the bad pwn.

@vickychijwani
Copy link
Owner

Yes, this is an issue I'm aware of, and yes, you are right that it is caused by JavaScript's rules around this. do creates a new JavaScript function scope, which is why the value of this changes.

@vickychijwani vickychijwani changed the title Scoping issue this scoping issue Jul 13, 2015
@freeman42x
Copy link
Author

I used a function definition to get past the scoping issue:

(defn attack [enemy]
  (if (< (.distanceTo this enemy) 5)
    (.attack this enemy)
    (.shield this)))

(dotimes [n 1000]
  (let [enemy (.findNearestEnemy this)]
    (if enemy
      (attack enemy)
      (.moveXY this 40 34))))

Are there any temporary hacks to get this usable inside the do?

@freeman42x
Copy link
Author

Same issue in ifs:

(dotimes [n 1000]
  (def enemy (.findNearestEnemy this))
  (if enemy
    (if (< (.distanceTo this enemy) 5)
      (.say this "message")
      (if (.isReady this "cleave")
        (.cleave this enemy)
        (.attack this enemy)))))

"message" never gets said.

@freeman42x
Copy link
Author

Another scoping oddity, this works:

(let [x this]
  (dotimes [n 1000]
    (def enemy (.findNearestEnemy x))
    (.say x (str enemy))
    (if enemy
      (if (< (.distanceTo x enemy) 5)
        (if (.isReady x "cleave")
          (.cleave x enemy)
          (.attack x enemy))))))

if (.say x (str enemy)) is removed then the attacks no longer work.

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

2 participants