Passing string and block do in ruby method - ruby

Trying to pass a block in the method:
self.handler_method("pinterest", do |pinterest|
handle_facebook(pinterest.get_facebook[:username]) if pinterest.facebook_found?
handle_twitter(pinterest.get_twitter[:username]) if pinterest.twitter_found?
end).call(username)
Which keeps returning error:
syntax error, unexpected keyword_do_block (SyntaxError)
self.handler_method "pinterest", do |pinterest|
^
How can I fix it such that it accepts both arguments. I can do the inline block way {} but would rather the expanded with do, end
Thanks

It should be:
self.handler_method("pinterest") do |pinterest|
handle_facebook(pinterest.get_facebook[:username]) if pinterest.facebook_found?
handle_twitter(pinterest.get_twitter[:username]) if pinterest.twitter_found?
end.call(username)

Related

Ruby error with non-required arguments on method [duplicate]

This question already has answers here:
How to mix required argument and optional arguments in ruby?
(2 answers)
Closed 6 years ago.
This is on Ruby 2.1.8.
I have the following method:
def self.notify(methods=[], user, message_key, notifiable_id=nil, notifiable_type=nil)
# Do some stuff
end
When I try to use this method and pass in valid values, I get the following error:
SyntaxError:
: syntax error, unexpected '=', expecting ')'
...er, message_key, notifiable_id=nil, notifiable_type=nil)
... ^
: Can't assign to nil
...message_key, notifiable_id=nil, notifiable_type=nil)
...
For the life of me I cannot figure out why. If I remove the =nil from notifiable_id and notifiable_type in the method arguments, everything works fine.
And FWIW assigning methods to an empty array is not the issue. If I don't assign that or assign it to nil I get the same issue.
Any thoughts appreciated.
You have a default defined for the 'methods' argument but then no defaults for user or message_key. You cannot have any arguments without a default value after an argument with a default value.

Ruby String interpolation throws syntax error in 1.9.3 but not 2.3.1

Sorry in advance for the large chunk of code. I'm concerned that I may have missed something that is obvious in context.
def remove_runbook_items(runbook_id, runbook_item_id)
item_id = runbook_item_id.to_s
method = 'POST'
url = #the_endpoint
data = {
invokeDetail: {
process: 'remove_runbook_items',
parameters: {
runbook_id: runbook_id,
runbook_items: {
"#{item_id}": {
cores: options[:cores],
ram: options[:ram],
rank: options[:rank],
wait_time: options[:wait_time]
}
}
}
}
}
data.merge! #common_data
result = send_request(method, url, data.to_json)
result['resultDetail'] # Returns contents of response from REST API server
end
The offending line is the one that says "#{item_id}": {
The block of text called "data" is converted into a json, so I must interpolate the string "item_id" or else it will literally spit out "item_id" in the resulting request, rather than item_id's contents. Actually, if there's a way to get at the contents without interpolation, I'd love to know it.
So when I interpolate my string in this way, it works just fine on Ruby 2.3.1. However, when I try to run the same code on a machine using Ruby 1.9.3, I get a litany of syntax errors anywhere I have interpolated a string like this:
/home/mydir/mydir/mydir/mydir/mydir/restapi_helper.rb:1122: syntax error, unexpected ':', expecting tASSOC
"#{device_id}": {
^
/home/mydir/mydir/mydir/mydir/mydir/restapi_helper.rb:1128: syntax error, unexpected '}', expecting keyword_end
/home/mydir/mydir/mydir/mydir/mydir/restapi_helper.rb:1163: syntax error, unexpected ':', expecting tASSOC
"#{item_id}": {
^
/home/mydir/mydir/mydir/mydir/mydir/restapi_helper.rb:1169: syntax error, unexpected '}', expecting keyword_end
/home/mydir/mydir/mydir/mydir/mydir/restapi_helper.rb:1257: syntax error, unexpected ':', expecting tASSOC
"#{item_id}": {
^
/home/mydir/mydir/mydir/mydir/mydir/restapi_helper.rb:1263: syntax error, unexpected '}', expecting keyword_end (SyntaxError)
Does anybody have any advice? Upgrading the version of ruby on the test machines is unfortunately not an option.
It is not iterpolation that is the problem.
{ symbol: value } is a new syntax, which is a shortcut for { :symbol => value }. In its first iteration, I don't think it supported { "symbol": value } automatic string symbolification feature. Use the old-fashioned { "symbol".to_sym => value } if backward compatibility is a goal.
(If you know that all you're doing is converting to JSON, you can even just leave it as { "string" => value }, comforted by the knowledge that JSON does not make a distinction between strings and symbols; but I'd consider it a code smell.)

Using a heredoc as a hash value

I have a method Embed.toggler that takes a hash argument. With the following code, I'm trying to use a heredoc in the hash.
Embed.toggler({
title: <<-RUBY
#{entry['time']}
#{entry['group']['who']
#{entry['name']}
RUBY
content: content
})
However, I'm getting the following error trace:
syntax error, unexpected ':', expecting tSTRING_DEND
content: content
^
can't find string "RUBY" anywhere before EOF
syntax error, unexpected end-of-input, expecting tSTRING_CONTENT or tSTRING_DBEG or tSTRING_DVAR or tSTRING_END
title: <<-RUBY
^
How I can avoid getting this error?
Add a comma after your <<-RUBY:
Embed.toggler({
title: <<-RUBY,
#{entry['time']}
#{entry['group']['who']
#{entry['name']}
RUBY
content: content
})
this does work in general. I am not sure why it wasn't working in my code though.
It didn't work because hashes require key/value pair to be separated by a comma, like {title: 'my title', content: 'my content' } and your code just didn't have the comma. It was hard to see that because of the cumbersome HEREDOC syntax.
Do you know if there is a way to perform operations on the string?
You're playing with fire. It's always safer (and usually cleaner) to extract a variable and do post-processing on a variable itself:
title = <<-RUBY
#{entry['time']}
#{entry['group']['who']
#{entry['name']}
RUBY
Embed.toggler(title: title.upcase, content: content)
However, if you feel dangerous today, you can just add operations after opening HEREDOC literal, just as you've added the comma:
Embed.toggler({
title: <<-RUBY.upcase,
#{entry['time']}
#{entry['group']['who']
#{entry['name']}
RUBY
content: content
})
But I discourage you from this because it destroys readability.

Ruby Error: syntax error, unexpected tGVAR, expecting $end

I am getting Ruby Error: syntax error, unexpected tGVAR, expecting $end.
I am using Mechanize to access a website and then I need to enter data into the form to search. When I pp page the site to get the form information I get:
#<Mechanize::Form
<name nil>
<method "POST">
<action "">
<fields
...
...
[text:0xb43f9c type: text name: ct100$MainContent$txtNumber value: ]
...
My code that is throwing this is:
Check_form = page.form()
Check_form.ct100$MainContent$txtNumber = 'J520518'
Any ideas on what is causing the error? Thank you in advance for the help!
Since this is not a valid variable or syntactically valid method name, you should use the alternate method to fetch or assign the values:
check_form = page.form
check_form['ct100$MainContent$txtNumber'] = 'J520518'
Variables are of the form #x for class instance variables, ##x for class variables, $x for global variables and x for plain variables, but in all cases the variable must consist of a letter or underscore followed by any number of letters, numbers, or underscores. $ cannot appear anywhere but the beginning, and when it does that means "global variable", something rarely used in most Ruby programming.
The error is telling you that there is a global variable where Ruby doesn't expect one. And there is: $txtNumber is a global variable, but it doesn't make sense for a global variable to appear at that place in your code.
Another way to make it legal would be
Check_form.send(:"ct100$MainContent$txtNumber=", 'J520518')

Ruby send(attribute.to_sym) for Rails Method

I'm using Ruby 1.9.2 and need to go through all of the values for a table to make sure everything is in UTF-8 encoding. There are a lot of columns so I was hoping to be able to use the column_names method to loop through them all and encode the values to UTF-8. I thought this might work:
def self.make_utf
for listing in Listing.all
for column in Listing.column_names
column_value_utf = listing.send(column.to_sym).encode('UTF-8')
listing.send(column.to_sym) = column_value_utf
end
listing.save
end
return "Updated columns to UTF-8"
end
But it returns an error:
syntax error, unexpected '=', expecting keyword_end
listing.send(column.to_sym) = column_value_utf
I can't figure out how to make this work correctly.
You're using send wrong and you're sending the wrong symbol for what you want to do:
listing.send(column + '=', column_value_utf)
You're trying to call the x= method (for some x) with column_value_utf as an argument, that's what o.x = column_value_utf would normally do. So you need to build the right method name (just a string will do) and then send the arguments for that method in as arguments to send.

Resources