Since Squeak is purely Object Oriented I'm fairly certain that you should be able to pass functions as parameters to other functions, but when I was researching on this I couldn't find any information about this. Is my intuition correct? And if so, how is it done and how do I invoke them afterwards?
Longer answer.
To pass a piece of executable code to a method, use a block.
The method definition is
method: aBlock
aBlock value
and you execute it as follows
object method: [ Transcript show: 'hello' ].
if you want to pass a parameter to the piece of code, use a block with an argument.
The method definition is
method: aBlock
aBlock value: 'parameter'
and you execute it as follows
object method: [ :arg | Transcript show: arg ].
the same can be done with 2 or unlimited parameters, using the methods value:value: and valueWithArguments: of the block.
If you pass in a symbol, you can also use value: to execute it. A symbol is actually equivalent to a block of the form [ :arg | arg symbol ].
You're confusing two different things. The only real "functions" you pass around in Smalltalk are blocks, which you pass just by writing a block as an argument (like you do with every ifTrue:). If you want to send a message to an object but have the message be determined dynamically, you can pass the message name as a symbol (e.g. #value) and send it to some object (e.g. with perform:). You don't pass instance methods themselves. Either pass a selector symbol or pass a block that sends a message to call the method.
Related
I have a third party API that has an event listener adding function which takes as parameter a callback function to be triggered when the event occurs. I would like to pass argument to that callback function. I'm looking for Lua's equivalent of JavaScript's bind.
The Lua code:
EventListenerAddingFunction(myCallbackFunction); // I want to add a param to the callback here
How I would do it in JS:
EventListenerAddingFunction(myCallbackFunction.bind({}, myParameter));
Can this be done in Lua?
No Lua doesn't have this feature, so closest I can think of would be making a closure-wrapper:
EventListenerAddingFunction(function(...) myCallbackFunction({}, myParameter, ...) end)
This passes your parameter everytime the callback is called, all other callback parameters will be passed next. If you don't know your parameters use ... (I don't know them so I used varargs), it's better if you pass exact amount of parameters.
I have methods generated for a list of symbols. One of the methods includes a question mark in its definition. I want to invoke such a method with a variable holding that symbol.
Suppose we generate a method for :check_element symbol and the corresponding method signature would look like.
class A
def check_element?
end
end
Now I have a variable flag = :check_element and I'm unable to call the method like A.send(flag)
but A.send((flag.to_s + '?').to_sym) works.
I'm thinking if there is a better way to achieve this.
There is no need to translate the method name argument to a symbol because send accepts a string too. That allows simplifying your example to
A.send(flag.to_s + '?')
Which can be simplified using string interpolation to
A.send("#{flag}?")
I'm trying to setup a mock function that will return a value which is based on the input. The only way to access the input parameter that I know of is via the WillExecute method. However, you have to specify a When clause, and that When clause expects me to define an input value along with the method, in the following fashion:
aMock.Setup.WillExecute(function ...).When.myFunc(1);
I'm kinda forced to say: call that anonymous function, whenever myFunc(1) is called. I'd like to be able to do the same, but on every possible parameter to myFunc, with a kind of wildcard marker in the parameter to myFunc (conceptually):
aMock.Setup.WillExecute(function ...).When.myFunc(*);
Is something like this possible? Basically a When clause that will match any value passed as parameter.
Someone might be tempted to point out the WillReturnDefault value, but method does not have access to the actual parameters of the call, as WillExecute does, so I won't be able to setup anything but a constant value.
Thanks.
Ok, I missed the fact that there was an overloaded version of WillExecute that will do exactly that:
//Will exedute the func when called with the specified parameters
function WillExecute(const func : TExecuteFunc) : IWhen<T>;overload;
//will always execute the func no matter what parameters are specified.
procedure WillExecute(const AMethodName : string; const func : TExecuteFunc);overload;
This way I can tell the mock to execute the passed anon whenever the method is called, regardless of its parameters, while still providing access to them. Exactly what I was looking for. Closing question. Thanks.
This can also be solved by using parameter matching:
aMock.Setup.WillExecute(function ...).When.myFunc(It0.IsAny<Integer>);
In the Rails documentation, the following example is given as a way to display what the server receives from a POST request:
def create
render plain: params[:article].inspect
end
In the subsequent description, the text states
The params method is the object which represents the parameters (or fields) coming in from the form. The params method returns an ActiveSupport::HashWithIndifferentAccess object.
While I understand that all methods are objects, I don't understand how it's correct to refer to the params object as a method. Specifically, the phrase "returns an ActiveSupport::HashWithIndifferentAccess object" suggests to me that there are two calls going on--what in python might look like:
params().__getitem__('article')
but I don't think that's what's actually going on.
The conversation around those lines also refers to params as a method, so I'm starting to think I must be missing something.
I'm new to Ruby, and while I understand that all methods are objects,
No, they aren't. Methods belong to objects (more precisely: methods are defined in modules, and executed in the context of objects), but they are not, by themselves, objects. (It is, however, possible to obtain a reflective proxy which represents the concept of a method by calling the method method, which returns a Method object.)
I don't understand how it's correct to refer to the params object as a method.
Because it is a method. Not an object.
What else would it be? Syntactically, it's obvious that it can only be one of three things: a keyword, a variable, or a method call.
It can't be a keyword, because Rails is just a Ruby library, and Ruby libraries can't change the syntax of the language (e.g. add or remove keywords). It can't be a variable, because in order for it to be parsed as a variable, the parser would need to have seen an assignment to it within the same block.
Ergo, the only thing it can possibly be, is a method call. You don't even need to know anything about Rails to know this. It's just basic Ruby syntax 101.
Specifically, the phrase "returns an ActiveSupport::HashWithIndifferentAccess object" suggests to me that there are two calls going on--what in python might look like:
params().__getitem__('article')
but I don't think that's what's actually going on.
That is exactly what is going on. You call the method params and then you call the method [] on the object that is returned by calling the method params.
This is in no way different from foo.bar: you call foo, then call bar on the return value of foo.
The params method is a method, returns a hash (which holds some details about parameters send to the app). Simplified it looks like this:
def fake_params
{ :controller => 'foo', :action => 'bar' }
end
You can call another method directly on the returned hash like this:
fake_params[:action] #=> 'bar'
params is a method defined in ActionController::Metal which returns the request.parameters object.
https://github.com/rails/rails/blob/master/actionpack/lib/action_controller/metal.rb#L140
I've found properties corresponding to each action named like this: MVC.<Controller>.<Action>Params, they contain parameter names for each action. What are they for and how they can be used?
There were some edge scenarios where it was interesting to pass the parameter name as a constant. I can't instantly recall what that person was doing, but I could see this being useful is calls to AddRouteValue. In the end, it's all about never to have to use a literal string that refers to a C# object, whether it's a class, method, or param.