I want to split up a large class by using mixins.
I am using this mixin code from the Little Book
#include: (obj) ->
for key, value of obj when key not in moduleKeywords
# Assign properties to the prototype
#::[key] = value
obj.included?.apply(#)
this
class FooMixin
b: => #something = 2
class Foo extends Module
#include FooMixin
a: => #something = 1
Problem is that # in FooMixin is FooMixin. I want it to be Foo instead.
I have tried adding the line _.bind(#::[key], #) at the end of #include() but it doesn't help. Any suggestions?
Okay, few things I was doing wrong.
1.
#include from the Little Book takes an object not a class. To get it to work with classes you need to write #include FooMixin::. However, I have since begun using objects instead.
2.
When using an object instead of a class, the fat arrow adds a line inside the CoffeeScript wrapper right at the top which reads _this = this. All methods are bound to the global context which is not what we want. To fix we must convert fat arrows to thin arrows, and bind each function to our Foo instance. Using Underscore I added this to the constructor of Foo:
constructor: ->
for fname in _.functions FooMixin
#[fname] = _.bind #[fname], #
super
I tried _.bindAll #, _.functions FooMixin but it gave me an error saying something like At Function.bind, could not run bind of undefined. Weird error, seeing as the code above is pretty much identical to the _.bindAll method.
So now I can split my classes up for better readability and code sharing.
UPDATE: The problem with _.bindAll is that it takes a splat not an array. Fix is to use _.bindAll #, _.functions(FooMixin)....
UPDATE: Found a better solution.
Same as original post. Use classes for mixins.
Use #include FooMixin:: or change #include to operate on a prototype instead of properties.
In the Foo constructor write FooMixin.call # which binds the methods correctly.
This works well and is nice and clean.
The only potential issue is that mixins will be overridden by existing properties. The only way to get around this that I can see is to do something like:
after = ->
_.extend Foo, FooMixin::
class Foo
# define...
after()
Or pass the extend method to _.defer but this is so hacky and probably won't work.
Related
I'm new to C++ and am exploring the use of timezones in chrono, specifically zoned_time.
I have only one issue with it: I want to use an instance of zoned_time as a member in a class, but no matter how I alter the syntax, the compiler doesn't like it.
#include <chrono>
#pragma once
class Event
{
private:
std::chrono::zoned_time tz;
public:
Event();
};
I've created a header file containing the code above, but it says the argument list for the class template is missing. I assume that means it wants me to initialize it, but I don't want to because it's a header file. As I said, I messed around quite a bit with the syntax of tz, combined with a good bit of research. Unfortunately, since I'm new to the language I really don't know what to look for online.
So my goal here is to be able to create a typed container within Event which will store the zoned_time information. I'm not picky on how I achieve that goal (I suspect some black-magic pointer trickery will be the solution). Thank you for the input.
Your error message mentions the word "template", indicating it's not about constructor arguments (initializer), but about generic type arguments (template parameters).
According to https://en.cppreference.com/w/cpp/chrono/zoned_time this class is declared as:
template <
class Duration,
class TimeZonePtr = const std::chrono::time_zone*
> class zoned_time;
So it seems like you need a duration type to use (there is a default for the time zone pointer type). So your line should probably say something like
std::chrono::zoned_time<std::chrono::seconds> tz;
I'm using CoffeeScript to create a class and build a private method, but my code feels kludgy.
As in the example below, first I define the method with = and then I am forced to use the call method on the portion to be used. But this seems like a kludgy workaround, so I want to know if there is a cleaner solution.
class Human
constructor: (#name, #height, #weight) ->
_realWeight = ->
#weight
answerWeight: ->
console.log(_realWeight.call(#) - 5)
$ ->
ken = new Human('Ken', 165, 70)
ken.answerWeight()
TL;DR
No.
Longer Answer
There is only one way to have truly private data in javascript/coffeescript: closures.
First, lets consider some alternatives:
Symbols
Because symbols are unique they can be used to create psuedo-private data:
you can only access the property if you have a reference to the symbol its keyed to:
foo = Symbol('I am unique')
bar = {}
bar[foo] = "I am almost private"
Code that doesn't have access to foo can't easily get to that property of bar except for Object.getOwnPropertySymbols. So not easy to break, but breakable.
Underscores
Typical naming convention says that properties/methods prefixed or followed by an underscore are 'private', they are not to be used by an external caller. However, that 'privacy' is not in any way enforced by the runtime.
So lets talk about closures.
Simple Closure example
makeFoo = (something) -> getSomething: -> something
foo = makeFoo(3)
foo.something # undefined
foo.getSomething() # 3
Now there is no way to get at the parameter passed to the constructor except to call the method. This pattern, while slightly more elegant in coffeescript, is still kinda lame. Lots of duplicated function objects. Not so bad for just getSomething, but add a bunch of methods and it gets ugly fast. Also, typically not as easily optimized by the JIT compiler as foo = new Foo() would be. Fortunately, ES 2015 to the rescue:
Advanced Closure Example
Foo = null
do ->
privateData = new WeakMap()
getSomething = -> privateData.get(this)
Foo = class Foo
constructor: (something) -> privateData.set(this, something)
getSomething: getSomething
foo = new Foo(3)
foo.something # undefined
foo.getSomething() # 3
new Foo(42).getSomething() # 42
foo instanceof Foo # true
Now all instances of Foo share one copy of getSomething rather than each getting their own. The weakmap is hidden in the closure created by the IIFE, and because of the 'weak' part of WeakMap when the instance gets garbage collected the private data will be as well. You are also now potentially able to enjoy the benefits of the compiler optimizing newly created objects. Last but not least, instanceof still works properly (to the extent that it ever works properly).
Further reading.
Even More reading
Note
WeakMaps are not supported in all browsers (for IE its 11 or bust). There is a shim, but it cannot be completely polyfilled. Whether or not the shim gets close enough is a call you'll have to make.
I'm struggling with some unwanted side effects of exposing a class in boost.python. It seems that in Python, it is legal to assign to a member variable that was never defined in the original class. So in the example below I define a class with a member 'a', but also writing to a member 'b' works in Python. This has the (in my case negative) side effect that I can't detect typos when accessing class members, since myClass.complicatedObjectName=1 works and myclass.complicatedObjectname=1 works as well, even if the latter variable is never defined. As illustration, when exposing a class like this
#include <boost/python.hpp>
using namespace boost::python;
class A {
public:
A() : a(1) {}
int a;
};
BOOST_PYTHON_MODULE(liba) {
class_<A>("A", init<>())
.def_readonly("a", &A::a);
}
and trying to acces A.a and A.b
import liba
myA = liba.A()
print "a", myA.a
myA.b = 1
print "b", myA.b
generates the output:
a 1
b 1
I would prefer the assignment 'myA.B = 1' to fail. Is there a way to make boost.python behave like this?
I'm sorry if this question is already asked somewhere, but I couldn't find an answer. Thanks for pointing me to existing answers if there is one.
I'm working with the standard boost libraries (v 1.54) on Ubuntu 14.04.
In python you can override _setattr_ to only allow attribute names from a defined list. Here is how to do that: https://stackoverflow.com/questions/3079306/how-to-protect-againt-typos-when-setting-value-for-class-members.
Then some ideas how to achieve the same in C++: How to override __setattr__ in a wrapped class (from C++)? and Catch creation of instance attributes of boost::python-wrapped classes from c++.
In CoffeeScript, I'd like to be able to assign the super method to a variable without calling it.
class a
one: ->
class b extends a
one: ->
mySuper = super
However doing the following actually calls the super method rather than returning it - here's the compiled code:
return mySuper = b.__super__.one.apply(this, arguments);
How do I actually assign the super method to a variable rather than calling it?
I know I could do:
class b extends a
one: ->
mySuper = b.__super__.one
But it isn't that clean.
Coffee script provides no syntax sugar for this use case. So do it yourself.
I would do it like this:
class B extends A
one: ->
mySuper = A::one
mySuper.call this # calls the saved super method
Example
:: is a shorthand for prototype. So A::one compiles to A.prototype.one which is where your super method actually is.
But this seems like a red flag to me. I can't think of a case where this would be a good idea. I'd wager it's not part of the language because if you design your classes properly, you shouldn't need this. You say you want something clean, but the thing you want to do here I wouldn't consider clean at all.
I'm just starting with X++ (Java background) and I found a code like
#XYZBatchScheduling
;
...
order.Status = #geplant;
order is a record to a table with a Status column.
My question: what is the meaning of #USRBatchScheduling and #geplant ("geplant" is "planned" in german) and eventually where to find it's definition.
I suppose it is some kind of constant but was unable to find # in the X++ reference (keywords).
#XYZBatchScheduling is a Macro library. Look in the AOT under Macros for XYZBatchScheduling.
#geplant is a Macro, it is probably defined in the XYZBatchScheduling macro library, but it could be defined in several other places. It could be defined in the class declaration of the class the method is in, or if the class is a derived class, in the class declaration of any of the base classes. Look for a line that looks like:
#define.geplant(42)