Please explain "keyword arguments" and give some examples of their use.
A function may use positional arguments and/or keyword arguments. Function arguments are used to provide functions with values developed outside of the function itself, values the function needs to know. For a given function, the actual value assigned to a specific argument may change from one call to the next.
A positional argument holds the place for specified value by its ordinal position in the function's argument list. For example, x and real, imag are positional arguments in these function definitions:
sqrt(x) = x^0.5
complex(real, imag) = real + imag*im
A keyword argument holds the place of a specified value by its name. The last (rightmost) positional argument comes before the first keyword argument. A semicolon (;) demarks the start of keyword arguments, even when there are no positional arguments. When both kinds of argurment are used, the semicolon separates the positional from the keyword arguments. For example, digitcount and digits are keyword arguments in this function definition:
roundedstring(x; digitcount) = string(round(x, digits=digitcount))
Here is an example that only uses keyword arguments:
function pathname(; dirpath, filename)
return joinpath(dirpath, filename)
end
dir_path = "/home/workfiles"
file_name = "current.txt"
path_name = pathname(dirpath=dir_path, filename=file_name)
# pathname == "/home/workfiles/current.txt"
Here is almost the same example, using both kinds of argument:
function pathname(dirpath; filename)
return joinpath(dirpath, filename)
end
dir_path = "/home/workfiles"
file_name = "current.txt"
path_name = pathname(dir_path, filename=file_name)
# pathname == "/home/workfiles/current.txt"
One reason to use keyword arguments:
function copyfile(; source, dest)
# function body
end
src_pathname = "~/current.txt"
dst_pathname = "/home/workfiles/current.txt"
# now both of these work
copyfile(source = src_pathname, dest = dst_pathname)
copyfile(dest = dst_pathname, source = src_pathname)
Using a keyword argument to allow changing a default setting:
function translate(text; language="en")
# translation function body
end
Using a keyword argument to require something:
#=
If the keyword `language` is not specified
when calling this function, a error occurs.
=#
function translate(text; language)
# translation function body
end
Both kinds of argument may have default values to use when an argument is omitted in a function call. All positional arguments that do not specify a default value must preceed all positional arguments that do specify default values. Keyword arguments have the same requirement, any with a default value must follow all keyword arguments that do not specify a default value.
Please see the docs for more information on keyword arguments and optional keyword arguments.
Related
I am trying to subtract two integer values as such:
But I get this error:
Unable to process template language expressions in action 'Negative_Index_of_Snabel-a' inputs at line '0' and column '0': 'The template language function 'sub' expects its first parameter to be an integer or a decimal number. The provided value is of type 'String'. Please see https://aka.ms/logicexpressions#sub for usage details.'.
I know that my variables in the sub() function is in quotes. But I cannot save it otherwise.
You're passing in literal string values, you need to specify that the values you want to evaluate are variables, like thus ...
sub(variables('VarMailInt'),variables('VarSnabelaIndex'))
I am calling a vbScript from PowerShell, with arguments that are defined in a text string, and I want to validate that the arguments being used are correct. Say my valid arguments are ARG1, ARG2 & ARG3, and someone has a string of "/ARGG1:one /ARG2:two", I want to validate the named arguments against an array of valid arguments and catch that ARGG1.
Where I am failing is in getting the names of the named arguments. I can reference a particular named argument with WScript.Arguments.Named("ARG1") for example. But I can't seem to loop through WScript.Arguments.Named and return the actual argument names used.
Something like this
For Each Argument In WScript.Arguments.Named
msgBox Argument.name
Next
When iterating the Named argument collection you are accessing the key (argument name) not the WshNamed object itself. If you pass the key back into the collection you will be able to access the value for that Named Argument.
Dim key
For Each key In WScript.Arguments.Named
Dim argument: argument = WScript.Arguments.Named.Item(key)
Call WScript.Echo(key) 'Return argument name
Call WScript.Echo(argument) 'Return argument value
Next
Output:
ARG1
one
ARG2
two
I'm creating a ruby command line tool which has a switch case statement, I'd like to pass through variables on this switch case statement for example:
input = gets.chomp
case input
when 'help'
display_help
when 'locate x, y' # this is the bit i'm stuck on
find_location(x, y)
when 'disappear s'
disappear_timer(s)
when 'exit'
exit
else
puts "incorrect input"
end
Essentially I want the user to be able to type in locate 54, 30 or sleep 5000 and then call a function which handles the number they passed. I was wondering how I can either pass arguments from the user in a switch statement like this for my command line tool like this?
Use Regexp matcher inside when:
when /locate \d+, \d+/
find_location *input.scan(/\d+/).map(&:to_i)
Here we basically match whatever is locate followed by digits, comma, space, digits. If matched, we extract the digits from the string with String#scan and then convert to Integers, finally passing them as an argument to find_location method.
I am working with a custom renderer, and I used some copy paste from another site. I can't seem to figure out what this piece is doing right here.
"#{options[:callback]}(#{data})"
Here is the piece of code in full context.
ActionController.add_renderer :as3 do |data, options|
data = ActiveSupport::JSON.encode(data) unless data.respond_to?(:to_str)
data = "#{options[:callback]}(#{data})" unless options[:callback].blank?
self.content_type ||= Mime::JSON
self.response_body = data
end
It's simple string interpolation. It will produce a string like this, where callback is the value of options[:callback], and value is whatever is in the variable data.
"callback(value)"
In Ruby, double-quoted strings support interpolation via #{} syntax. That is, if you have a variable x containing the value 3, the string "The value of x is #{x}" will be evaluated to "The value of x is 3". Inside a #{} you can have any arbitrarily complex Ruby expression, including array/hash indexing. So, the first part of the string, "#{options[:callback]}" is simply substituting the value of options[:callback] into the string.
The next part, the () is simply raw string data, not executable code. Inside the (), you have a second #{} substitution of data. It might be clearer if you replace the two variable substituions with x and y:
x = 3
y = 4
"#{ x }(#{ y })"
The above will evaluate to the string "3(4)"
This is converting a JSON response to JSONP; imagine data is:
'{"some": "thing", "goes": "here"}'
JSONP states that the data should be wrapped in a JavaScript function call. So of options[:callback] is the string test (the name of the function to call), the resulting JSONP would be:
'test({"some": "thing", "goes": "here"})'
It's a template that replaces the first field with the value of options poiinted to by the interned string :callback, and the second field, inside the parens with the contents of data.
I'd bet a buck that the resulting string is going to be eval'd somewhere else, where it will become a call to a procedure. That would work something like this:
options[:callback] = "foo"
data="arg,arg,arg"
(Notice that data is being encoded into JSON, so the string passed as data is a json string.
The string then turns into "foo(arg.arg.arg)", and when it's eval'd it becomes a call to routine foo with those arguments.
http://www.ruby-doc.org/core-1.9.3/Kernel.html#method-i-eval
Update:
Actually, I take it back about the Ruby eval -- although that would work, it's more likely turning into a Javascript function call. This would then let you pass the name of a javascript function as a string and the code would return the appropriate callback function for execution by javascript later.
You can rewrite
"#{options[:callback]}(#{data})"
as
options[:callback].to_s + "(" + data.to_s + ")"
Consider the following string which is a C fragment in a file:
strcat(errbuf,errbuftemp);
I want to replace errbuf (but not errbuftemp) with the prefix G-> plus errbuf. To do that successfully, I check the character after and the character before errbuf to see if it's in a list of approved characters and then I perform the replace.
I created the following Ruby file:
line = " strcat(errbuf,errbuftemp);"
item = "errbuf"
puts line.gsub(/([ \t\n\r(),\[\]]{1})#{item}([ \t\n\r(),\[\]]{1})/, "#{$1}G\->#{item}#{$2}")
Expected result:
strcat(G->errbuf,errbuftemp);
Actual result
strcatG->errbuferrbuftemp);
Basically, the matched characters before and after errbuf are not reinserted back with the replace expression.
Anyone can point out what I'm doing wrong?
Because you must use syntax gsub(/.../){"...#{$1}...#{$2}..."} or gsub(/.../,'...\1...\2...').
Here was the same problem: werid, same expression yield different value when excuting two times in irb
The problem is that the variable $1 is interpolated into the argument string before gsub is run, meaning that the previous value of $1 is what the symbol gets replaced with. You can replace the second argument with '\1 ?' to get the intended effect. (Chuck)
I think part of the problem is the use of gsub() instead of sub().
Here's two alternates:
str = 'strcat(errbuf,errbuftemp);'
str.sub(/\w+,/) { |s| 'G->' + s } # => "strcat(G->errbuf,errbuftemp);"
str.sub(/\((\w+)\b/, '(G->\1') # => "strcat(G->errbuf,errbuftemp);"