I'm writing a WxPerl program and instead of
$panel->SetDropTarget( MyTextDropTarget->new($panel) );
I wrote
$panel->SetDropTarget->( MyTextDropTarget->new($panel) );
and Perl didn't complain. (Perl called some function with some arguments, and the script did error out with an error message:
Usage: Wx::Window::SetDropTarget(THIS, target) at ./x.pl line 230.
I'm curious as to how Perl parsed the 'wrong' version.
Added edit:
Okay, so if $x = \&some_function, then I understand why
$x->($arg1, $arg2, ...)
calls some_function($arg1, $arg2, .....).
runrig's example is one possibility, but I'm quite sure that:
1) $panel contains a blessed object reference, not a string.
2) SetDropTarget is a method (in a base class) of $panel.
From the error message we can assume that SetDropTarget() being called. If runrig's example still applies here (and I'd guess it does), then even though SetDropTarget isn't followed by parentheses, i.e. I have
$panel->SetDropTarget->
instead of
$panel->SetDropTarget()->
Perl is still invoking SetDropTarget? (which inspects the number and type of its arguments and then fatally complains at runtime). Is that what happens?
Because it's perfectly valid syntax. $panel->SetDropTarget->( MyTextDropTarget->new($panel) ) means "Call the &SetDropTarget method from $panel, and then dereference the subref that &SetDropTarget returns." It's not what you meant to write, I'm guessing, but any error thrown would be at runtime, even in strict mode.
Your SetDropTarget likely does not return a code reference, but you can't tell that until runtime:
#!/usr/bin/perl
my $panel = 'main';
$panel->SetDropTarget->("bloomin'");
sub SetDropTarget {
return sub { print "Set the $_[0] drop target!\n" }
}
Perl parsed
$panel->SetDropTarget->( MyTextDropTarget->new($panel) );
to mean "$panel is an object; call its SetDropTarget method (optional parenthesis omitted), which will return a reference to a sub; call that sub, passing the the result of MyTextDropTarget->new($panel) as its single parameter."
That is, Perl expected SetDropTarget to be something like foo in the following code:
sub foo {
return sub {
my $bar = shift;
return $bar . ', world!';
}
}
foo()->('Hello');
foo->('Goodby');
Related
I would like this code:
[1,2,3].all? {|x| x.is_a?(Integer)}
to work using the &: method like:
[1,2,3].all?(&:is_a?(Integer))
but I get this error:
syntax error, unexpected '(', expecting ')'
I guess it's because I am calling is_a?(Integer) as a symbol.
How can I pass Integer to :is_a??
It is impossible. You cannot pass Integer (or anything else) to a symbol :is_a?. A symbol does not take an argument. No object in Ruby takes an argument (without a method call).
By the way, there is no such thing as &:.
You can get close to the notation you want with a lambda:
is_an_int = ->(o) { o.is_a?(Integer) }
[1,2,3].all?(&is_an_int)
or even closer, a lambda which returns a lambda:
is_a = ->(c) { ->(o) { o.is_a?(c) } }
[1,2,3].all?(&is_a[Integer])
Possibly more trouble than it is worth in this case but useful techniques none the less.
What is the Perl 6 way to tell the difference between an argument and no argument in a block with no explicit signature? I don't have any practical use for this, but I'm curious.
A block with no explicit signature puts the value into $_:
my &block := { put "The argument was $_" };
The signature is actually ;; $_? is raw. That's one optional argument. The #_ variable isn't defined in the block because there is no explicit signature.
There's the no argument, where $_ will be undefined:
&block(); # no argument
But there's also a one argument situation where $_ will be undefined. A type object is always undefined:
&block(Int);
But, an $_ with nothing in it is actually an Any (rather than, say, Nil). I can't tell the difference between these two cases:
&block();
&block(Any);
Here's a longer example:
my $block := {
say "\t.perl is {$_.perl}";
if $_ ~~ Nil {
put "\tArgument is Nil"
}
elsif ! .defined and $_.^name eq 'Any' {
put "\tArgument is an Any type object"
}
elsif $_ ~~ Any {
put "\tArgument is {$_.^name} type object"
}
else {
put "\tArgument is $_";
}
};
put "No argument: "; $block();
put "Empty argument: "; $block(Empty);
put "Nil argument: "; $block(Nil);
put "Any argument: "; $block(Any);
put "Int argument: "; $block(Int);
Notice the no argument and Any argument forms show the same things:
No argument:
.perl is Any
Argument is an Any type object
Empty argument:
.perl is Empty
Argument is Slip type object
Nil argument:
.perl is Nil
Argument is Nil
Any argument:
.perl is Any
Argument is an Any type object
Int argument:
.perl is Int
Argument is Int type object
As far as I know, the only way to know the number of parameters passed without an explicit signature, is to use #_ inside the body, which will generate a :(*#_) signature.
my &block := { say "Got #_.elems() parameter(s)" };
block; # Got 0 parameter(s)
block 42; # Got 1 parameter(s)
dd block.signature; # :(*#_)
Yeah, the good old #_ is still there, if you want it :-)
{ put $_.perl }
Is sort of similar to this: (which doesn't work)
-> ;; $_? is raw = CALLERS::<$_> { put $_.perl }
Since the default is default for $_ outside of the block is Any, if you don't place anything into $_ before you call the function you get Any.
To get something at all similar where you can tell the difference use a Capture :
my &foo = -> ;; |C ($_? is raw) {
unless C.elems {
# pretend it was defined like the first Block above
CALLER::<$_> := CALLER::CALLERS::<$_>
}
my $called-with-arguments := C.elems.Bool;
if $called-with-arguments {
say 'called with arguments';
} else {
say 'not called with arguments';
}
}
Here's how I solved this. I'd love to do this in a cleaner way but the cleverness of the language gets in the way and I have to work around it. This works for positional parameters but there are deeper shenanigans for named parameters and I won't deal with those here.
I had another question, Why does constraining a Perl 6 named parameter to a definite value make it a required value?, where the answers clarified that there are actually no optional parameters. There are merely parameters that have a default value and that there is an implicit default value if I don't explicitly assign one.
The crux of my problem is that I want to know when I gave the parameter a value and when I didn't. I give it a value through an argument or an explicit default. An implicit default is a type object of the right type. That's Any if I didn't specify a type. That implicit default must satisfy any constraint I specify.
The first goal is to tightly constrain the values a user can supply when they call code. If an undefined value is not valid then they shouldn't be allowed to specify one.
The second goal is to easily distinguish special cases in the code. I want to reduce the amount of special knowledge some part of the deeper code needs to know.
I can get the third case (where I know there was no argument or suitable default) by explicitly assigning a special value that I know can't be anything other meaningful thing. There's a value that's even more meaningless than Any. That's Mu. It's the most undefined values of all undefined values. The Any is one of two subtypes of Mu (the other is Junction) but you should almost never see a Mu end up in one of your values in normal code. Undefined things in user code start at Any.
I can create a constraint that checks for the type I want or for Mu and set a default of Mu. If I see a Mu I know there was no argument and that it's Mu because my constraint set that.
Since I'm using Mu there are some things I can't do, like use the === operator. Smart matching won't work because I don't want to test the inheritance chain. I can check the object name directly:
my $block := ->
$i where { $^a.^name eq 'Mu' or $^a ~~ Int:D } = Mu
{
say "\t.perl is {$i.perl}";
put do given $i {
when .^name eq 'Mu' { "\tThere was no argument" }
when Nil { "\tArgument is Nil" }
when (! .defined and .^name eq 'Any') {
"\tArgument is an Any type object"
}
when .defined {
"\tArgument is defined {.^name}"
}
default { "\tArgument is {.^name}" }
}
};
put "No argument: "; $block();
put "Empty argument: "; try $block(Empty); # fails
put "Nil argument: "; try $block(Nil); # fails
put "Any type argument: "; try $block(Any); # fails
put "Int type argument: "; try $block(Int); # fails
put "Int type argument: "; $block(5);
Now most of those invocations fail because they don't specify the right things.
If these were routines I could make multis for a small number of cases but that's an even worse solution in the end. If I had two parameters I'd need four multis. With three such parameters I'd need six. That's a lot of boilerplate code. But, blocks aren't routines so that's moot here.
As an example: getche() I understand what getche does, but why the () at the end?
If you are not putting anything in the parenthesis, why do you need them to be there? Just because of standards?
Thanks
Whether a function/method call needs to have parentheses at the end is a syntax particularity that varies from language to language. In Ruby, for example, you don't need it, while in Java, you do.
The compiler can use it to determine that you're making a function/method call. In many languages, you can reference a function as an object, so you need the parentheses to distinguish a reference to a function from a call to a function.
For example, in javascript:
function something(){
return "hello";
}
var a = something;
var b = something();
The variable a will contain the actual function something, while the variable b will contain "hello".
It executes the function without passing any parameters.
In languages with first-class functions, foo and foo() have different meanings. Consider these two examples, in Lua:
local bar = foo -- Assigns foo to bar. bar is now the function at foo.
local bar = foo() -- Executes foo, and assigns the return value to bar.
This, of course, depends on the language you are using. For example, in Haskell, no parenthesis are used to call functions.
This is syntax for Method/function.
Why is the need of it ? Because in the () you can provide the input arguments as well.
like for example :
var sum = addition(3,4);
Here addition can be defined as:
int addition(int a, int b)
{
return (a+b);
}
Currently investigating migrating from mvBase to Unidata and would like to know if User Defined Functions are supported as I cannot see this in the documentation I have downloaded?
e.g I have DATABASIC program with something like
A = #FUNCTION_NAME(VAR1)
Yes, Unidata supports user defined functions.
To create a function in Unidata, use a line like this on line 1 of the code file:
FUNCTION MY.FUNCTION.NAME( ARG1, ARG2 )
Inside the function, use the RETURN statement to return a result:
RETURN ARG1 + ARG2
To call it, you have to indicate that you're going to use it with the DEFFUN statement in the program that will use the function:
DEFFUN MY.FUNCTION.NAME( ARG1, ARG2 )
I usually put my DEFFUN statements near the top of the program, right after any $INCLUDEs. (The parameter names don't have to match between the FUNCTION and DEFFUN lines, but I don't know of any reason to purposefully make them different.)
After that setup, you can call the function by using its name in an expression:
TOTAL = MY.FUNCTION.NAME( 10, 15 )
After that statement, TOTAL will have a value of 25.
I've never seen a function called with the #FUNCTION_NAME syntax in Unidata.
In Lua I've created a pretty printer for my tables/objects. However, when a function is displayed, it's shown as a pointer.
I've been reading up on Lua Introspection but when I introspect the function with debug.getinfo() it won't return the function's name. This seems to be due to a scoping issue but I'm not sure how to get around it.
What is the best way to get a function's name using its pointer? (I understand functions are first class citizens in Lua and that they can be created anonymously, that's fine)
when you create the functions, register them in a table, using them as keys.
local tableNames = {}
function registerFunction(f, name)
tableNames[f] = name
end
function getFunctionName(f)
return tableNames[f]
end
...
function foo()
..
end
registerFunction(foo, "foo")
...
getFunctionName(foo) -- will return "foo"
For some reason, it seems to work only with number parameters (that is, active functions on the stack).
The script
function a() return debug.getinfo(1,'n') end
function prettyinfo(info)
for k,v in pairs(info) do print(k,v) end
end
prettyinfo(a())
prints
name a
namewhat global
but if I change the last line to
prettyinfo(debug.getinfo(a, 'n'))
it gives me only an empty string:
namewhat