I have simple class in coffeescript (this class is located in file.js.coffee):
class ExampleClass
constructor: (arguments) ->
makeSTH: (page) ->
makeSTHElse: (data) =>
I have another coffee file. I included above file and I tried to create instance of ExampleClass this way:
/#= require file.js.coffee
class ExampleClass2
constructor: (arguments) ->
#ex = new ExampleClass(sth)
But I got something like this:
ReferenceError: ExampleClass is not defined
I don't know how to correctly reference to ExampleClass. Thanks for all answers and sorry for my English.
CoffeeScript will compile each of the source file as a separated compilation unit. Each of the compilation unit will be wrapped inside a block, so that the global namespace won't be polluted by mistake. So, ExampleClass actually get compiled to something like:
(function () {
var ExampleClass;
ExampleClass = function (args) {}
...
}).call(this);
You can see that ExampleClass can only be accessed from the same source. In order to access it from other source file, you need to bind it to window.
class window.ExampleClass
constructor: (args) ->
...
PS. you're not allowed to use arguments as formal parameter name in CoffeeScript, as it has special meaning in JavaScript.
And /#= require file.js.coffee is not valid in CoffeeScript, you need to remove the leading /. I think that's just a typo.
Related
Let me be more specific here: This is used in Unity 2017 so the syntax they are using is this:
class CameraMotionBlurEditor extends Editor
{
var preview : SerializedProperty;
var previewScale : SerializedProperty;
...
function OnInspectorGUI () {
if (preview.boolValue) dosomething()
}
}
What I'm getting errors in is this preview.boolValue reference.. it claims it's ambiguous so therefore whatever this class is extending, must also have a declaration of that variable name. What I don't know is how to specify the local one.
The this keyword is used to refer to the current instance of the class. Retrieving the preview.boolValue from the current instance of the class hence becomes this.preview.boolValue:
function OnInspectorGUI () {
if (this.preview.boolValue) dosomething()
}
Note that UnityScript is slowly becoming deprecated, and the recommended route of action is to instead program Unity scripts in C#.
I want to join (use) classe in Coffescript files, and i found some usefull ideas here (sry for not including all links), since none fitted my needs (at least not as i like) I tried to find an own solution, this will work fine, but is there something I have overseen?
following "base" and "base class" are not OO words, I just did not find better names
I have a base (class) file TechDraw
class TechDraw
constructor: ->
$(window).load () =>
... do somthing
wave_to_me: ->
say 'I wave' # say is a basic func, I always use for debugging (console.log)
#TechDraw = new TechDraw
this works fine
Now I want to expand/extend my class with "sub classes/modules" in other files; ie. I have a TechDrawLine, and a TechDrawCalc, ans so on
What I did, was building a coffee file for each of them like:
class TechDrawConnector
constructor: (p)->
#parent=p
wave: (msg) ->
say 'yes its me, the connector:',msg
`window.TechDrawConnector = function(p) { return new TechDrawConnector(p) };`
# the last instead of a simple new like
# #TechDrawConnector = new TechDrawConnector
and my base(ic) class/module I extendet like this:
class TechDraw
constructor: ->
$(window).load () =>
#Connector=window.TechDrawConnector(this)
#LineGuy=window.TechDrawLineGuy(this)
#Connector.wave('init')
Since I am a newbee in coffeescript (yes javascript also) my solution feels to simple ...
Have I overseen somthing? The Polution of the global namespace is not so bad I think
You cant create an "extension" that way.
If you define the same class in the same namespace a second time the first class will simply be overwritten and become in accessible. This will mostly be dependent on the order of loading of the compiled JavaScript files.
However you could either later add an method to the prototype of the class
#file a.coffee
class A
constructor: ->
#foo()
#file B.coffee
A::foo = -> #do something
However this is no good style and can certainly be very confusing some time and lead to brittle errors.
Better would be to use a form of dependency injection
#file a.coffee
class A
constructor: (#closure) ->
$(window).load () => #closure()
#file B.coffee
new A () ->
#Connector=window.TechDrawConnector(#)
#LineGuy=window.TechDrawLineGuy(#)
#Connector.wave('init')
This works :
class Foo
class #_Bar
#narf = ''
#point : ->
#narf = 'what'
class #_Baz extends #_Bar
#point : ->
#narf = 'woo'
super()
This does not
class Foo
class #_Bar
#narf = ''
#point = ->
#narf = 'what'
class #_Baz extends #_Bar
#point = ->
#narf = 'woo'
super()
running Foo._Baz.point() will throw and error.
Please someone explain what is going on here.
It seems like a bug in the compiler to me. Writing
class X
#classMethod: ->
and
class X
#classMethod = ->
should be equivalent, yet super compiles differently across the two methods. In the first, it compiles correctly:
X.__super__.constructor.classMethod.apply(this, arguments);
In the second, it compiles as if classMethod were an instance method:
X.__super__.classMethod.apply(this, arguments);
This works:
class Foo
class #_Bar
#narf = ''
point : ->
#narf = 'what'
class #_Baz extends #_Bar
#point = ->
#narf = 'woo'
super()
alert Foo._Baz.point() # 'what'
alert new Foo._Bar().point() # 'what'
That is, the compiled #point= super ends up pointing to the instance point:. Its JS is: _Baz.__super__.point.call(this), which is _Bar.prototype.point.call(this). (extends defines: child.__super__ = parent.prototype).
It's clear from past Coffeescript changes that #point: is the intended syntax for static (class) methods (and used that way in the compiler itself).
There are a couple of fixes now on github. https://github.com/jashkenas/coffee-script/issues/3232
Currently the node tree for a #foo= method is different from that of a #foo: method. Because of that, a node created with = is never passed to the Class addParameters method, and is never flagged as static.
One solution, which will probably be accepted, makes sure both forms produce the same node tree.
The one I contributed https://github.com/jashkenas/coffee-script/issues/3232#issuecomment-28316501
adds a method to nodes.coffee class Class. This method is a stripped down version of addParameters, and specifically checks a = node tree.
If you need a fix in your own Coffee compiler, modify your src/coffee-script/nodes.coffee file, compile it, and put the resulting node.js in the lib directory (or use the cake build).
I have a "class" in coffee script whose instance variables I want to initialize with instance methods that return a value via a callback, but it doesn't work as I had hoped:
EventEmitter = require('events').EventEmitter
class MyClass extends EventEmitter
constructor: ->
#datamember: setDatamember()
setDatamember: ->
someFunction (response) ->
#datamember = response
#emit 'init'
getDatamember: ->
return #datamember
----
myObj = new MyClass
myObj.on 'init', ->
console.log myObj.getDatamember
The result I get suggests that "this" in setDatamember is referring to something different from what "this" refers to in the object instance. If I explicitly call myObj.setDatamember, I get the expected result, but is there any way to call on a set method -- specifically one that sets the data member via a callback -- in the constructor? I've looked through the docs, as well as various other sources of coffeescript info (e.g. this one), and I haven't found anything that touches upon this.
Try using a fat arrow for the anonymous function:
setDatamember: ->
someFunction (response) =>
#datamember = response
#emit 'init'
Also, you'll need to call the correct function in the constructor:
constructor: ->
#setDatamember()
In general, avoid fat arrows on methods - the way Coffee-Script implements this does some bad things to memory usage. Also, it will rarely be necessary.
However, anonymous functions that refer to this will almost always need fat arrows. this is not held in closure like normal variables, and will only be set by binding (Function.prototype.bind) or by calling it as an object method (obj.myMethod() will set this to obj in myMethod).
Try using fat arrows on everything except the constructor:
class MyClass
constructor: ->
#setDatamember()
setDatamember: =>
someFunction (response) =>
#datamember = response
getDatamember: =>
return #datamember
However, you also look to have someFunction in there as an asynchronous function, so you'll never be able to just do
mc = new MyClass
console.log mc.datamember
Because that doesn't wait for someFunction to return before accessing mc.datamember.
I have a helper assembly which includes a function to identify object types:
namespace Util
{
using namespace System;
public ref class CastingHelpers
{
public:
template < class T, class U >
static System::Boolean isinst(U u);
static bool Test() {return true;}
};
}
...but for some reason, when I try and use it in a gui application which references the assembly:
Util::CastingHelpers::Test();
Util::CastingHelpers::isinst<SomeClass^>(someInstance);
..gives me an error:
2>.\DataProcessor.cpp(161) : error C2039: 'isinst' : is not a member of 'Util::CastingHelpers'
Note that test works fine. Is this something to do with the fact that isinst uses generics?
You are not creating a generic function, you are creating a C++ template function which is not exported from the assembly.
Use the keyword generic instead of template to create .NET generic types and methods.
The template method is only visible by code that #includes its declaration.