Having a bit of hardtime understanding coffeescript. Why is this the window object in the set_position function?
window.App = {}
$ ->
driver = new Driver if ($('#drivers_become').length >= 1)
window.App.driver = driver
class Driver
constructor: ->
#get_position()
get_position: ->
if navigator.geolocation
navigator.geolocation.getCurrentPosition(#set_position)
set_position: (pos) ->
# this refers to window object in this case. why?
#latitude = pos.coords.latitude
#longitude = pos.coords.longitude
get_latitude: ->
#latitude
get_longitude: ->
#longitude
get_latitude and get_longitude return undefined in this case.
If you are using aDriverInstance.set_position as an event handler function, the browser will invoke it as a regular function not a method. To fix that, use a "fat arrow" when defining it: set_position: (pos) =>. But more broadly it is a question of invoking via dot notation and invoking via direct reference:
aDriverInstance.set_position(pos) will have this set to aDriverInstance and all is well
set_position_reference = aDriverInstance.set_position;set_position_reference(pos) will have this set to the window object.
This is a classic binding issue, and applies as much to Javascript as Coffeescript.
You are passing a Driver method, set_position to a Windows function,
navigator.geolocation.getCurrentPosition(#set_position)
That function evaluates set_position in the global, windows, context. In effect it ends up setting global latitude and longitude variables, not the attributes of the Driver instance. In your console see if those variables are defined.
What you want to do is define set_position so #is bound to the Driver instance. To do that, use the fat arrow, =>. http://coffeescript.org/#fat-arrow
set_position: (pos) =>
# this refers to window object in this case. why?
#latitude = pos.coords.latitude
#longitude = pos.coords.longitude
If you use this, and look at the compiled Coffee, you will see a line that does:
this.set_position = __bind(this.set_position, this);
Packages like jquery and underscore also have a bind function, as do recent browsers.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
get_position: ->
if navigator.geolocation
navigator.geolocation.getCurrentPosition(#set_position.bind(this))
Uses the browser's bind
Related
I'm sorry I'm new to LUA scripts and I have to work on code written by others.
Please don't focus on code, my problem is only about included files and priority evaluating which function has to be called, in case of overriding.
Let's say I have a file Terrain.lua containing a class Terrain, which has a function Terrain:generate() and Terrain:generate() calls Terrain:getLatitude().
Terrain was included in a script MyScript.lua, which overrided Terrain:getLatitude() as follows:
include("Terrain");
function Terrain:getLatitude()
new code;
end
function myFunction()
local myTerrain = Terrain.create();
myTerrain.generate();
end
This has the effect of overriding getLatitude(): when myTerrain.generate() is called, generate() is the code from the included "Terrain", but getLatitude() is the local function with the new code, even if called by a function from the included class.
Now let's say I want to put some of the code in an external file Custom.lua. Custom (and not MyScript) has to override getLatitude().
This is the situation:
Terrain.lua contains Terrain class and these functions
Terrain.create()
Terrain.generate()
Terrain.getLatitude()
MyScript.lua is the script being executed, and include Custom:
include("Custom");
function myFunction()
return customFunction()
end
Custom.lua contains:
include("Terrain");
function Terrain:getLatitude()
new code;
end
function customFunction()
local myTerrain = Terrain.create();
myTerrain.generate();
end
Now, if I call customFunction() from MyScript, getLatitude() from Terrain is used, instead of getLatitude() from Custom. I assume ovveride is possible only inside the currenti file being executed? How can I achieve overriding in an included file?
I hope this example is enough to understand my problem, without posting a lot of code. Thank you.
Firstly, some corrections: there is no local function's in your question; include is not part of any lua standard, what that function actually does may be quite important.
Finally, Lua does not have actual class system, what you use in the question is merely a syntactic sugar (misleading and confusing as I find it) over table assignments. Lua is an interpreted language, so what may seem to you as a class definition is not a static structure known from the very beginning of the program execution but a code that gets executed from the top of the file to the bottom.
Thus, if we assume that include is similar to the require, then the your question code will be equivalent to the following:
do--terrain.lua
Terrain = {
create=function()
local created_object
--some code to assign value to created_object
return created_object
end
}
Terrain.generate = function(self) end
Terrain.getLatitude = function(this_is_a_self_too)
--some code that uses `also_self` as a reference to the object when called as object:generate()
end
--do end block is essentially an equivalent of file, its local variables are not seen outside
--global variables it has assigned (like `terrain`) will stay accessible AFTER its end
--changes it done to global variables will also remain
end
do--Custom.lua
Terrain.getLatitude = function(this)--this is the assignment to a field in a table stored in the global variable Terrain
--this function will replace the one assigned to the `getLatitude` field
end
customFunction = function()
local myTerrain = Terrain.create();
myTerrain.generate();--this one probably needs `:` instead of `.`
--depends on actual code inside terrain.lua
end
end
do--MyScript.lua
myFunction= function()
return customFunction() --this line calls the global variable customFunction
end
end
Thus if your actual setup is similar to the one in question, then the "override" will take effect after the Custom.lua is executed and for all the subsequent calls to the Terrain.getLatitude regardless of whether or not they've called the file. (And any later file can override it again, and all calls after that will be using the new one)
It is probably more complicated to do a limited override in this setup. That again depends on the actual details of how your team has defined the Terrain class and the class system itself.
Imagine that coffeescript class :
class Batman
constructor: ->
alert "Batman is awesome"
I think it's a rookie question, but what's the real difference between :
class #Batman
constructor: ->
alert "Batman is awesome"
and
class window.Batman
constructor: ->
alert "Batman is awesome"
Compile your coffeescript using the '-c' argument and see what you get:
(function() {
/// Your code here
}).call(this);
That this there is the context of the function wrapper being called, and becomes the this object inside your coffeescript module.
In the context of a browser, your module is initialized with the global this = window; in the context of a Node or IoJS, this = global, the global context of execution; in the context of plv8, this = role, a per-execute object that contains security information (since plv8 is basically node run inside a SQL server, this is important to have).
class window.Batman explicitly attaches your Batman class to a window object (which means you no longer have isomorphic code you can use everywhere); class #Batman attaches it to the local context, which can be, well, whatever you want it to be.
All in all, as a best practice, attaching stuff to VM-supplied contexts (like the browser, your node instance, your database) is generally not a good idea, and you should find a better way to instantiate your code and pass it from module to module.
Perhaps I'm using the wrong search terms, or maybe eclipse just doesn't support this, but when I type a function call to a function that I haven't written yet, is there a way to have eclipse automatically create an empty placeholder function with the same name?
I'm using FDT to do ActionScript3 coding, if that makes any difference.
For example, if I type this:
var x = func(5.2);
but I haven't written the func function yet, eclipse will underline func to alert me that it can find a reference to that function. This is presenting me with a problem, but not a solution. Is there a keyboard shortcut to have eclipse automatically go to this:
var x = func(5.2);
private function func():void {
// add your code here...
}
Use Ctrl-1 (Windows) or Cmd-1 (MacOS).
I am using Akka and scala. And so I am calling either system.actorOf or context.actorOf in my code. However, I am wrapping Akka's library for actor creation so I can add certain functionality. So, the issue arises with how to allow my higher-level abstractions to work in either context. Whether they are called within an environment where system is available (in test code and at the app's kernel) or if they are called within an actor (and only have access to the context variable).
Getting this slapped together and working is easy. Can just make a function that takes both context and system implicitly and returns an ActorRef based on whichever is available. However, to weed out even more duplication I've run into a problem.
There are many other places I'd want to access whichever is in scope (either context or system) automatically. For example, if I want to call system.config or context.system.config, I need to create yet another wrapper function for just that situation.
I'd like to be able to do something like this:
appropriate.actorOf(Props[Whatever], name = "breakfast")
and the appropriate function returns whichever is available (either actor or system) and then I'd use this function in every place where there is a switch case between the two.
The problem that I run into is that if I return Either[ActorContext, ActorSystem] from a function, I get an error that actorOf is not available on that type. So, it's checking it based on the type, not the fact that it's available on either type no matter which is returned.
Is there a way to do what I am attempting?
You should use the subtype ActorRefFactory to make this generic as both ActorContext and ActorSystem inherit from it. You can either return it from your function which figures out which type to return or you can fold the Either that you mentioned:
val either:Either[ActorContext, ActorSystem] = ...
val refProvider = either.fold[ActorRefFactory](ac => ac, as => as)
refProvider.actorOf(Props[Whatever], name = "breakfast")
UPDATE
To answer your question in the comments, first, you're creating an Either object so you shouldn't expect to have any method of it's contents available on it. Either holds a left or right object and is an object itself with it's own methods. The fold over Either takes two functions, one with takes a left type and returns a new data type and another function with takes a right type and returns the same data type. By using fold, we can get a value out of the either. If you want to a more in depth look at how this works I highly recommend Functional Programming in Scala.
Additionally, you can simplify your code and remove the either all together as it's really unnecessary in your context:
def appropriateContext(implicit context: ActorContext = null, system: ActorSystem = null): ActorRefFactory = {
if (context != null) context else system
}
For anyone else who finds this, this is the solution I ended up with:
def appropriateContext(implicit context: ActorContext = null, system: ActorSystem = null): ActorRefFactory = {
val either: Either[ActorContext, ActorSystem] = if (context != null) Left(context) else Right(system)
val refProvider = either.fold[ActorRefFactory](ac => ac, as => as)
refProvider
}
and then I can call
appropriateContext.actorOf(Props[Whatever])
This is missing the error handling that I'll add (what to do if both are in scope or neither) but is working.
I want to manage part of my layout with coffeescript. I have a left/right panel and I want to be able to switch between them. I have created something like this:
window.switchPanel = (panel = 'left', action = 'toggle') ->
open = (panel) ->
...
close = (panel) ->
...
toggle = (panel) ->
...
My question is, how do I structure this so that I can call open/close/toggle by the action variable and can I use something so that I don't have to pass in the panel to every child function? Perhaps #panel?
I think you just want to throw your functions into an object so that you can access them by name:
window.switchPanel = (panel = 'left', action = 'toggle') ->
funcs =
open: (panel) ->
...
close: (panel) ->
...
toggle: (panel) ->
...
Then you can simply funcs[action](panel) inside switchPanel. If you don't want pass panel into the functions then you don't have to, they'll have access to panel simply by being defined within switchPanel:
window.switchPanel = (panel = 'left', action = 'toggle') ->
funcs =
open: ->
...
close: ->
...
toggle: ->
...
Then you'd just funcs[action]() and they could do what they like with panel.
Demo: http://jsfiddle.net/ambiguous/UV42x/
Some reading on JavaScript closures would clarify what's going on in the second version.
You might want to include an if(action !of funcs) check to make sure you don't try to use a bad action. Or, as Aaron Dufour notes in the comments, you could funcs[action]?() if you only need to check that action is valid once.
Few things:
1) I think you're creating obvuscated architecture by selectively calling methods within the object based on an input to the object. It begs the question "Why even create the methods? Why not just use a big IF ELSE IF type structure?" But others would disagree with me.
2) This is one of the confusing circumstances of CoffeeScript. You're dealing with something that would normally be clear if wrapped in explicit braces. I don't like javascript's crazy use of anonymous function wrappers everywhere, but I do believe in bracketed code. I defer to point 1. I think you're just making things more complicated by doing it this way.
3) Have you studied how coffeescript transforms the 'this' keyword? I'm pretty certain CoffeeScript does some kind of smart transformation on 'this' that deviates from standard javascript, which will mean nobody can answer this question for you except Coffee users. It won't be the same as javascript. Its relevant because in order to access 'panel' in the methods without passing it explicitly, you would need to use 'this.panel' or some other dereferencing mechanism to access the panel member from within one of the methods. I can't tell you how, but this information my help steer you in the right direction. The issue at hand is clearly a question of how to reference object members.