Sailsjs 0.12 - Custom method for all models - sails.js

I am trying to add Laravel-like Mass Assign to my Sails 0.12 application.
So far I have done:
Add method secureUpdate to config\models.js:
console.log(this);
var self = this;
var modelName = self.adapter.identity.charAt(0).toUpperCase() + self.adapter.identity.slice(1);
I am trying to get the calling model name, just like in seed method in this gist(for seeding data): https://gist.github.com/juanpasolano/5c7596d8629eeeb8debd#file-config-models-js
But the value of this is diffirent, with no adapter object(undefined)
I do not understand why the value of this is not the same. Could you help me out?

I write the answer here just for others who may have the same problem in the future :
The this is undefined because you are defining the method as an arrow function, you have to use a function expression, from MDN :
An arrow function expression has a shorter syntax than a function expression and does not have its own this, arguments, super, or new.target. These function expressions are best suited for non-method functions, and they cannot be used as constructors.

Related

Error "Inout argument could be set to a value with a type other than ..." when passing in a protocol type

I am coming from C++ to Swift. I have this situation with respect to protocols and structs (I am working with random numbers):
(1) A protocol RandomPr that specifies there are methods such as randFloat() that returns a Float between 0 and 1.
(2) A struct RandomS that implements RandomPr using a "real" random number generator.
(3) A struct FakeRandomS that implements RandomPr, but has additional methods such as loadFloat() to load an array of Floats that are then regurgitated when I call randFloat() on a FakeRandomS instance. (For testing purposes.)
Now I have a function DoSomething(rng: inout RandomPr), which I want to use with both RandomS and FakeRandomS. The parameter has to be in-out as I need to update the RNG (whether it is real or fake). No problem calling DoSomething with an instance of RandomS.
But if I do
var fakeRng = FakeRandomS()
fakeRng.loadFloat([0.1, 0.2, 0.3])
DoSomething(rng: &fakeRng)
I get an error "Inout argument could be set to a value with a type other than 'FakeRandomS'. The suggested fix is to define fakeRng as
var fakeRng: RandomPr = FakeRandomS()
But now trying to call loadFloat on fakeRng fails because RandomPr doesn't have a method loadFloat, and the compiler doesn't see that fakeRng does have one.
I tried making another protocol FakeRandomPr that contains the extra methods that FakeRandomS has, and defining
var fakeRng: RandomPr & FakeRandomPr = FakeRandomS()
but, frustratingly, I now get the "Inout argument could be set to a value with a type other than ..." error back again.
I could do the equivalent of this in C++ without problems (a pure abstract base class and two child classes, passed in by reference), and it didn't matter that one of the things I wanted to pass in has extra methods. I want to translate this into protocols and structs. What is the Swift solution?
What is the Swift solution?
You may need to use generics:
func doSomething<RP: RandomPr>(rng: inout RP) {
//...
}
Swift is not just another syntax of C++, better think in Swifty way.

I can't figure out how this switch statement is working?

func performMathAverage (mathFunc: String) -> ([Int]) -> Double {
switch mathFunc {
case "mean":
return mean
case "median":
return median
default:
return mode
}
}
I got this example from a swift learning book and its speaking of the topic of returning function types and this is just a part of the whole program I didn't want to copy and paste it all. My confusion is that the book says:
"Notice in performMathAverage , inside the switch cases, we return
either mean , median , or mode , and not mean() , median() , or mode()
. This is because we are not calling the methods, rather we are
returning a reference to it, much like function pointers in C. When
the function is actually called to get a value you add the parentheses
suffixed to the function name. Notice, too, that any of the average
functions could be called independently without the use of the
performMathAverage function. This is because mean , median , and mode
are called global functions ."
The main question is: "Why are we not calling the methods?"
and what do they mean we are returning a reference to it??
What do they mean by reference? Im just confused on this part.
You stated your main question as:
"Why are we not calling the methods?" and what do they mean we are returning a reference to it??
This is a little tricky to grasp at first, but what it's saying is that we don't want the result of the function, we want the function itself.
Sometimes things like this are easier to understand w/ a type alias:
Starting w/ [Int] -> Int, what we're saying there is "a function that takes an array of Ints and returns a single Int"
Let's make a type alias for clarity:
typealias AverageFunction = [Int] -> Int
Now our function (from your example) looks like this:
func performMathAverage(mathFunc: String) -> AverageFunction {
Although, the naming conventions here are pretty confusing since we're not performing anything, instead let's call it like this:
func getAverageFunctionWithIdentifier(identifier: String) -> AverageFunction {
Now it's very clear that this method is functioning like a factory that returns us an average function based on the identifier we provide. Now let's look at the implementation:
func getAverageFunctionWithIdentifier(identifier: String) -> AverageFunction {
switch identifier {
case "mean":
return mean
case "median":
return median
default:
return mode
}
}
So now, we're running a switch on the identifier to find the corresponding function. Again, we're not calling the function because we don't want the value, we want the function itself. Let's look at how we would call this:
let averageFunction = getAverageFunctionWithIdentifier("mean")
Now, averageFunction is a reference to the mean function which means we can use it to get the mean on an array of integers:
let mean = averageFunction([1,2,3,4,5])
But what if we wanted to use a different type of average, say median? We wouldn't have to change anything except for the identifier:
let averageFunction = getAverageFunctionWithIdentifier("median")
let median = averageFunction([1,2,3,4,5])
This example is pretty contrived, but the benefits of this is that by abstracting a function out to it's type (in this case [Int] -> Int, we can use any function that conforms to that type interchangeably.
This is functional programming!
This has to do with the functional programming aspects of swift. Here functions are treated like first class citizens meaning you can treat them like variables.
Why are we not calling the methods?
You are not calling the methods, because you have no argument to apply. The point of the function is to determine which function you would like to use. Of course the name of the function is terrible and does not accurately represent what the function does. It should be more like func determineMathFuncToUse, then you could use it like
var myFunc = determineMathFuncToUse("median")
// Now, you would be able to use myFunc just like you would use median
// e.g. myFunc(some_array) == median(some_array)
This is pretty easy to understand. In Swift you can store references to functions (the closest you can achieve in Objective-C is the reference to block).
func performMathAverage (mathFunc: String) -> ([Int]) -> Double
This is the function whose return type is:
([Int]) -> Double
As you can see the return type of this function is a function which accepts an array of Int and returns Double.
And in code you see that it returns one of three functions: mean, mode, and median. Each of these functions accepts an array of Int and returns Double.
Due to this code below:
let meanFunc = performMathAverage("mean")
let mean = meanFunc(someIntArray)
is identical to:
let mean = mean(someIntArray)
I hope this helps.
The reason why functions are NOT executed in code is because this example illustrates how you can STORE reference to functions.
It might be difficult to understand why you would want to do it in this particular case, but, hey, printing "Hello world" also seems meaningless :)
You are referring to an example in a tutorial so it is not strange that they are oversimplifying things. However, believe me, that in a real world there are many cases in which storing references to functions is very-very useful!
One obvious example is when you want to store reference to some completion handler which you want to execute at the end of some lengthy operation. And which can be different depending on the context from which you initiated this operation.
To answer your question, you are effectively returning the function itself, and not the result of calling that function. In this case, it lets you choose a function (using the switch statement) and evaluate it later. A helpful way to think about it is that functions are also a type of variable, and you can pass them around as well as evaluate them.
As a general stylistic thing, it's good practice to end each case with a break. It makes no difference here because return will also end the execution of the function, but without a break, all code after the correct case will be executed, not just the code within the correct case. Running into another case statement doesn't break out of the switch statement by itself.
Why are we not calling the methods?
Presumably, the method will be called later. The purpose of the switch statement is to return a function that can be used later.
What do they mean we are returning a reference to it? ... What do they mean by reference?
The "reference" language is a bit confusing - functions are reference types, but that isn't super important to what is going on. You can think of it as just returning a function.
The bottom line is that functions in swift can be used like any other type - they can be stored in variable or constants, they can be passed into a function as a parameter, and they can be returned from a function.
In this case, you have a function that is designed to return a function. If you want to obtain the mean, you pass the string "mean" and the function will return a new function that will obtain the mean when you call it.

What's the proper way to declare a field holding a function in dart?

Imagine a silly class like this:
class ConditionalWorker{
var validityChecker= (inputs)=>true;
ConditionalWorker(this.validityChecker)
...
Now my question is, what is the proper way of declaring the validityChecker field?
This tutorial suggests using typedefs. But that's not very practical. Firstly it's a chore to write a lot of typedefs that would only be used once. And secondly these typedefs show up and pollute the autocompletion of my IDE.
The var works best, with custom setters/constructor arguments to keep it always of a specific kind, but I know it's discouraged by the style guide.
I could do Function<bool> but that just a more glorified var and the amount of work is the same.
It's a shame because it's perfectly legal to have a function like this:
bool every(bool test(E element));
where the parameter is a very well defined function, but I can't have a field declared the same way:
bool test(E element);
But hopefully there is something just as good that I didn't figure out. Right?d
If you want a function type more specific than Function, you need a typedef.
If you don't like to have named typedefs for every return type, you can define generic function types yourself.
typedef R function0<R>();
typedef R function1<S,R>(S arg1);
typedef R function2<S,T,R>(S arg1. T arg2);
typedef R function3<S,T,U,R>(S arg1, T arg2, U arg3);
Then you can write:
function1<int,int> curryAdd(int x) => (int y) => x + y;
Or if function0 looks bad to you, you can name them NullaryFunction, UnaryFuncytion, BinaryFunction, TernaryFunction, or any other name that you like.
If Function<bool> is not specific enough (you also want to specify the number and type of the arguments you have to use typedefs. There are no other ways.
I'm not sure why you think it is not practical. If you want to specify the type for a field that references a value you have to use one of the existing classes or create a new one. It's the same for fields referencing functions.
With Dart 2 we can use inline function types and we need to use it instead of typedefs where possible.
With inline function types we now can define a function as a field or a property as simple as this:
final bool Function(E) test;

Why is 'init' not assignable?

I just read that the init method can't be used as a value. Meaning:
var x = SomeClass.someClassFunction // ok
var y = SomeClass.init // error
Example found on Language reference
Why should it be like that? Is it a way to enforce language level that too dirty tricks come into place, because of some cohertion or maybe because it interferes with another feature?
Unlike Obj-C, where the init function can be called multiple times without problems, in Swift there actually is no method called init.
init is just a keyword meaning "the following is a constructor". The constructor is called always via MyClass() during the creation of a new instance. It's never called separately as a method myInstance.init(). You can't get a reference to the underlying function because it would be impossible to call it.
This is also connected with the fact that constructors cannot be inherited. Code
var y = SomeClass.init
would also break subtyping because the subtypes are not required to have the same initializers.
Why should it be like that?
init is a special member, not a regular method.
Beyond that, there's no reason that you'd ever need to store init in a variable. The only objects that could use that function in a valid way are instances of the class where that particular init is defined, and any such object will have already been initialized before you could possibly make the assignment.
Initializers don't have a return value. In order to assign it to something, it should be able to return something - and it doesn't.

Help with the Moles syntax for testing private method with generics

I've got a signature for a method that looks like this:
private IEnumerable BuildCustomerUpdatePlan(List localCacheChangedCustomers, List crmChangedCustomers){}
When I look at the moled object, the syntax (IntelliSense) of how to call the method and test itis absolutely confusing to me and every time I give it a shot, I get compilation errors. I've looked through the basic tutorials provided on MSFT's site, but I simply don't get how to test a private method using Moles or how to deal with the return type and multiple parameters.
Unfortuantely I've been unable to find other good HOWTO's or threads demonstrating a more complex sample than just working with a simple Add() method that spits out an INT and accepts an INT. :(
Tips?
In your testing project, first make sure you add a Moles assembly corresponding to the assembly-under-test. You'll also want to add an using statement of the assembly-under-test with .Moles appended so you can use the moled assembly.
Moles changes the names of the classes and methods to the form M[Original Class Name].[Original Method Name][typeof param1][typeof param2].... In your case a detour for that method could look like MClass.BuildCustomerUpdatePlanListList = (List x, List y) => { [code]};. That defines an anonymous method that takes two Lists as parameters and you'd put whatever code wanted in the function. Just make sure that you return an IEnumerable in that anonymous method.
Here's an example using Moles to detour Directory.GetFiles:
using System.IO.Moles;
[assembly: MoledType(typeof(System.IO.Directory))]
...
MDirectory.GetFilesStringString = (string x, string y) => new string[0];
Since the Directory class is a member of System.IO I use using System.IO.Moles; to specify that I want to use moled members of the assembly.
Moles requires you to specify the types Moled: [assembly: MoledType(typeof(System.IO.Directory))] does the job.
Finally, Directory.GetFiles takes two strings as parameters and returns a string array. To detour the method into returning the equivalent of no files found, the moled method just returns new string[0]. Curly braces are needed if you want multiple lines in the anonymous method and, if not detouring a void method, a return statement that matches the type the original method would return.