I am very new at Ruby and programming and I am trying to write this simple function below
def sum_square(x=0, y, z=0)
p x**2 + y**2 + z**2
end
sum_square(2,3)
and i get this error syntax error, unexpected '=', expecting ')'
I thought i could use optional argument here
Parameters with default values should be placed after parameters without default values or, as Tom Lord stated in comments, can be "placed anywhere else in the list, so long as they are all defined together". So, if you want to keep y mandatory it should be something like
def sum_square(y, x=0, z=0)
p x**2 + y**2 + z**2
end
But it can be confusing during calls, so you can switch to named params:
def sum_square=(y, x:0, z:0)
p x**2 + y**2 + z**2
end
# all these call are valid
sum_square(1)
sum_square(1, x:2)
sum_square(1, z:2)
sum_square(1, x:2, z:3)
There are more possible ways to implement this function listed in comments with more general approach (for any number of inputs using *) or with all params being named.
Related
I know when writing a function that takes a string, it looks like:
def function("string")
but how do I write one that takes an array? should I first define an empty array e.g. s=[] and then when writing the function, just use s as the input?
Please try this.
#here argument name can be anything. It not compulsory to use array as argument name, it can be anything like `string`, `xyz` etc
def function(array)
p array
end
function([1,2,3,4,5])
This is really a question about Ruby than Rails. Ruby is a dynamic typing language, which in method definition, means you don't declare the argument types:
def add_three ( x, y , z)
x + y + z
end
add_three(1, 2, 3) # 6
add_three('a', 'b', 'c') # 'abc'
add_three([2], [3], [4], # [2, 3, 4]
add_three(Date.new(2017,3,4), 1, 1), # new date 2017.3.6
What matters is that x has a method + that accepts y, and the result from x + y has a method + that accepts z. This is called duck typing. What's important here is not which class the object is, but what message it can respond to.
As Ruby is dynamic language and it supports Duck Typing we never declare the data type of the variables or arguments of the method. So you could pass the array in any method, ruby just cares about the methods you can use on that argument which is an object for it. So to be sure about the array methods you are using will execute on array only you can do like this:
def doSomething(value)
if (value.is_a?(Array))
value.any_array_method # For eg: value.include?('a')
else
raise "Expected array value"
end
end
And you can call it like:
doSomething(['a', 'b', 'c'])
and if you call it with any other argument than array then it will give:
RuntimeError: Expected array value
You can pass an error message too instead of raising an exception that depends on you.
Hope this helps.
You can do it by doing
def my_function(arr=[], s)
puts arr.inspect
puts s.inspect
end
you can call the method with
my_function([1,3,4], "string")
I have one variable that comes from a map, I'm trying to get a specific part between square brackets
(e.g."dmfkdmfk[IWANTTHISPART]mlkm")
but it isn't working by the way I did. I'm trying as same way used here.
Original Code:
query_values = activities.map do |activity|
'(' +
"#{activity['note']}"
+')'
end
I tried:
query_values = activities.map do |activity|
'(' +
"#{activity['note'].[/#{"["}(.*?)#{"]"}/m, 1]}"
+')'
end
Error log:
syntax error, unexpected '[', expecting '('
'(' + "#{activity['note'].[/#{"["}(.*?)#{"]"}/m, 1]},""'" +')'
^
quase.rb:40: syntax error, unexpected keyword_end, expecting tSTRING_DEND
How can I go through?
Many Thanks.
str = "(dmfkdmfk[IWANTTHISPART]mlkm)"
#1 Use a regex with lookarounds
R0 = /
(?<=\[) # match a left bracket in a positive lookbehind
.+ # match one or more of any character
(?=\]) # match a right bracket in a positive lookahead
/x # free-spacing regex definition mode
(same as R0 = /(?<=\[).+(?=\])/)
str[R0] #=> "IWANTTHISPART"
#2 Split string on a left or right bracket
R1 = /
[\[\]] # match a left or right bracket
/x
(same as R1 = /[\[\]]/)
str.split(R1)[1]
#=> "IWANTTHISPART"
#3 No regex
str[str.index('[')+1..str.index(']')-1]
#=> "IWANTTHISPART"
You cannot have a period after the receiver when using [] in its syntax-sugar form. The following is ungrammatical:
string.[regex, parameter]
Use either the ordinary method invocation form:
string.[](regex, parameter)
or the syntax-sugar form:
string[regex, parameter]
/\[(.*)\]/.match( "dmfkdmfk[IWANTTHISPART]mlkm" )[1]
=> "IWANTTHISPART"
You can use String#[] with a regular expression:
> a = "dmfkdmfk[IWANTTHISPART]mlkm"
> a[/\[.*?\]/][1..-2]
#=> "IWANTTHISPART"
I am trying to make a query to search for values in my hstore column properties. I am filtering issues by user input by attribute. It is possible to search Issues where email is X, or Issues where email is X and the sender is "someone". Soon I need to change to search using LIKE for similar results. So if you know how to do it with LIKE also, show both options please.
If I do this:
Issue.where("properties #> ('email => pugozufil#yahoo.com') AND properties #> ('email => pugozufil#yahoo.com')")
it returns a issue.
If I do this:
Issue.where("properties #> ('email => pugozufil#yahoo.com') AND properties #> ('sender => someone')")
Here I got an error, telling me:
ERROR: Syntax error near 'd' at position 11
I change the "#>" to "->" and now this error is displayed:
PG::DatatypeMismatch: ERROR: argument of AND must be type boolean, not type text
I need to know how to query the properties with more than one key/value pair, with "OR" or "AND", doesn't matter.
I wish to get one or more results that include those values I am looking for.
I end up doing like this. Using the array option of the method where. Also using the suggestion from #anusha in the comments. IDK why the downvote though, I couldn't find anything on how to do something simple like this. I had doubt in formatting my query and mostly with hstore. So I hope it helps someone in the future as sure it did for me now.
if params[:filter].present?
filters = params[:filter]
conditions = ["properties -> "]
query_values = []
filter_query = ""
filters.each do |k, v|
if filters[k].present?
filter_query += "'#{k}' LIKE ?"
filter_query += " OR "
query_values << "%#{v}%"
end
end
filter_query = filter_query[0...-(" OR ".size)] # remove the last ' OR '
conditions[0] += filter_query
conditions = conditions + query_values
#issues = #issues.where(conditions)
end
I am attempting to write my own solution to a Ruby exercise from Rubymonk where the purpose is to create three methods (add, subtract, and calculate) so when 'calculate' is called you can determine whether or not numbers are added or subtracted based on what is passed in. I am receiving the following error:
main:11: syntax error, unexpected '=', expecting ')' def calculate(*numbers, options={})
Can anyone tell me what the issue is with my code? Thanks for any and all help!
def add(*numbers)
numbers.inject(0) {|sum, number| sum + number}
end
def subtract(*numbers)
numbers.inject{|diff, number| diff - number}
end
def calculate(*numbers, options={})
result = add(numbers) if options.empty?
result = add(numbers) if options[:add]
result = subtract(numbers) if options[:subtract]
result
end
def calculate(*numbers, options={})
is not a valid method definition b/c *numbers takes the place a variable number of arguments. You have two options as I see it -
def calculate(options={}, *numbers)
or
def calculate(*args)
numbers, options = args[0..-2], args[-1] || {}
if you want to keep the same argument order
The splat argument *numbers needs to be the last argument. Otherwise, how would Ruby know when to treat the last argument as options or as the last number?
You can use (*numbers, options) (without a default value), but that would require that you always pass an options hash to the method (otherwise your last number will be set as the options variable instead).
Try this way:
def calculate(options={},*numbers)
Using optional arguments after the fully optional argument ( the * notation) do not work since it creates an ambiguity.
Read more at:
http://www.skorks.com/2009/08/method-arguments-in-ruby/
You can't use both a splat and a param with a default as last argument, this is too ambiguous for the parser (how to know that the last arg passed is meant to be the options?)
you can work around this in many ways ; one idiom from rails (active support) is :
def calculate(*args)
options = args.extract_options!
# ...
end
where extract_options! is a monkey-patch to Array from ActiveSupport defined as follow :
def extract_options!
last.is_a?(::Hash) ? pop : {}
end
as a side note :
an options hash is not really usefull here. you could pass in just a symbol as first argument, maybe.
if you use a hash, logic could be simpler :
def calculate(*args)
options = args.extract_options!
method = options.fetch(:method, :add)
send method, *args
end
on add, you don't need inject(0), injectuses the first element of your array as a first "memo" value if you don't provide one
you can pass a symbol to inject, which will be the method called on your "memo" value, with "next value" as argument :
(1..10).inject(:+)
# this is the same as
(1..10).inject{ |memo, next| memo + next }
# or, more exactly
(1..10).inject{ |memo, next| memo.send :+, next }
I have an attribute which name is alias and method which create_alias.I use create_alias method as before_validation callback.In the method decleration I have following lines
while ProjectType.find_by_alias(tmp) != nil
tmp = self.alias + "-" + i.to_s
i += 1
end
As you can see, the code tries to create unique alias but on rails 4.0 we encounter this error message.
SyntaxError: /home/vagrant/.rvm/gems/ruby-1.9.3-p194#comRails4/bundler/gems/rails-39555a5b1989/activerecord/lib/active_record/dynamic_matchers.rb:65: syntax error, unexpected keyword_alias, expecting ')'
def self.find_by_alias(alias, options = {})
Change your column name. As you see, alias is Ruby keyword and it shouldn't be used as column name.