I added a way in the latest Framer build to get rid of the "new" keyword. That means that where you used to type:
myLayer = new Layer width:200, height:200
You can now type:
myLayer = Layer width:200, height:200
If it has no weird side effects I will make this the default. You have to enable it by hand for now, just add this to the top of your document:
To try the latest builds you can select "File > Update Framer" in Framer Studio or download it here by hand: http://builds.framerjs.com/
It's an interesting design choice. It took me a while to understand you're designing a front-end framework for people who don't code... I'm curious to see where else this will lead. :)
How did you do this? A "this" check w/ "new" in the factory function (ie Layer,) or with Object.create?
Like this: https://github.com/koenbok/Framer/blob/master/framer/Extras/OmitNew.coffee
I'd love your input. You see any downsides?
How about configuration file(like config.js) or information comment at top of file? omit new, project title, default animation, etc.
It's a bit odd. And I'm pretty sure `return new Klass args...` is never reached. Have a look at this to see what I mean: http://jsfiddle.net/wjpzxmwL/
If this is the expected behaviour, then this is probably all you need: http://jsfiddle.net/nL3fykyg/
An alternate approach where you don't need a wrapper: http://jsfiddle.net/5s0h25rc/
An even better and my personal favorite: Using Object.create: http://jsfiddle.net/hmpzftrk/ (I was surpised to learn that the "calling with new case" actually works for this code, which I guess is good for all the class-based language converts who still want to write "new" ;) )
Wow thanks Rasmus, I learned a lot from that.
interesting choice - I think 'new' is pretty a pretty useful semantic signifier - like it's super obvious that you're creating a new thing rather than just referencing the class.
One thing that now makes me feel I need to keep the new keyword is a CoffeeScript thing:
If you type "layer = new Layer" you now get a new layer.
But if you type "layer = Layer" you won't. Only if you type "layer = Layer()".
So I'm on the fence for now... I'll keep it optional for a while.
Jon: the thing is I'm working on a Color class which would give us:
layer.backgroundColor = new Color(255,0,0,1).mix(new Color("red"), 0.5)
That would obviously better like this:layer.backgroundColor = Color(255,0,0,1).mix(Color("red"), 0.5)
Class method VS Instance method right?
how about having an OmitNew mixin that you can apply to classes?
(or yeah, better idea Jordan - what if Colour('red') was a class method that returned a new instance?)
So that is what we have today, it works both ways if you enable it. But I'm wondering what the default should be.
Koen instead of going this route, have you considered making helper functions instead that instantiate Color instances? For example: rgba(255,0,0,1) could return a red Color instance with opacity 1. Would also look more familiar I think to people familiar with CSS. You could still do rgba(255,0,0,1).mix("red", 0.5) but wouldn't have to resort to metaprogramming Color's class, which imo is cleaner and more predictable. In a similar fashion, you could also have a color() (mind the lowercase) function. Personally, I'd prefer Color.rgba(....) and Color.name('red') etc... as factory methods to keep the API clean and consistent.
^ Yes that's a solid approach.
I actually really like that Ninh. Explicit new plus designer friendly helper functions.
Koen Yep, everyone wins ;-) You might also want to apply the Flyweight pattern in this case for color objects if you go with the approach in my post, seeing as colors can be considered immutable and as such, can be pooled for re-use. That way, if people do rgba(255,0,0,1) or color('red') for instance 1,000,000 times, it'd just create 1,000,000 references to the same red color object as opposed to 1,000,000 red objects which should be way cheaper/more efficient/easier on the GC too: http://en.wikipedia.org/wiki/Flyweight_pattern . Needless to say, you can lazily instantiate these as needed and this is where "omitting the new keyword" (i.e. not having the caller directly instantiate an object) in favor of using a factory method/function is actually practical too. Not sure if that's a scenario you need to worry about upfront, but something to take into consideration if designers tend to create too many objects in a loop.