Syntax error in for loop (Ruby/RSpec) - ruby

While running the RSPEC test as shown below im getting this error:
Using Accessor#strict_set for specs
SyntaxError: /home/sam/projects/logstash.king-foo.dev/ansible/roles/logstash/spec/syslog.rb:6: syntax error, unexpected kEND
end
^
load at org/jruby/RubyKernel.java:1101
(root) at /opt/logstash/vendor/bundle/jruby/1.9/gems/rspec-core-2.14.7/lib/rspec/core/configuration.rb:1
each at org/jruby/RubyArray.java:1613
load_spec_files at /opt/logstash/vendor/bundle/jruby/1.9/gems/rspec-core-2.14.7/lib/rspec/core/configuration.rb:896
load_spec_files at /opt/logstash/vendor/bundle/jruby/1.9/gems/rspec-core-2.14.7/lib/rspec/core/configuration.rb:896
run at /opt/logstash/vendor/bundle/jruby/1.9/gems/rspec-core-2.14.7/lib/rspec/core/command_line.rb:22
I tried messing around with the syntax but without success.
files = Dir['../configs/filter*.conf']
##configuration = String.new
files.sort.each.do |file|
##configuration << File.read(file)
end
describe "my first logstash rspec test", :if => RUBY_ENGINE == "jruby" do
extend LogStash::RSpec
config(##configuration)
... some code here ...
end
Does anybody know what i'm doing wrong?
Why do i get a syntax error for the end statement ander the ##configuration variable?

The error means there was an unexpected end in your code. Just simply replace the 3rd line with
files.sort.each do |file|
I optionally recommend you use { and } instead of do and end. The { and } are space-insensitive and you are less likely to receive an error than do and end.

Related

Why is my program given an unexpected token: $end error?

Here is my unfinished code:
#When convert button is pressed
File.rename("*.osz", "*.zip$")
dialog.directory(
def extract_zip(file, destination) FileUtils.mkdir_p(destination)
file_path = "./convert_temp/*.zip"
destination = "./convert_temp/osz/"
extract_zip(file_path, destination)
until File.exists?( ".osu$" ) == false do
File.rename("./convert_temp/osz/*.osu$", "*.txt$")
File.foreach(filename) do |file|
file_string = File.read('./convert_temp/osz/*.txt$')
if file_string.include?('Mode: 1')
puts 'Yes'
else
puts 'No'
end
end
end
Robocop giving the following syntax error:
unexpected token $end (Using Ruby 2.2 parser; configure using `TargetRubyVersion` parameter, under `AllCops`)
Actually, Rubocop is not even able to parse the file, because it has syntax errors.
The error message syntax error: unexpected token $end means that the ruby parser was parsing along happily, but then it suddenly encountered an $end, which is the parser's way to say "the end of the file". It was expecting more code, but instead it found the end of the file.
This is what your code looks like with proper indentation:
#When convert button is pressed
File.rename("*.osz", "*.zip$")
dialog.directory(
def extract_zip(file, destination) FileUtils.mkdir_p(destination)
file_path = "./convert_temp/*.zip"
destination = "./convert_temp/osz/"
extract_zip(file_path, destination)
until File.exists?( ".osu$" ) == false do
File.rename("./convert_temp/osz/*.osu$", "*.txt$")
File.foreach(filename) do |file|
file_string = File.read('./convert_temp/osz/*.txt$')
if file_string.include?('Mode: 1')
puts 'Yes'
else
puts 'No'
end
end
end
Using this kind of indentation makes it easy to see that there are some missing ends/parentheses, because the last line is left hanging in the air instead of closing back to the left edge where it started from.
Additional notes:
dialog.directory(
def extract_zip(file, destination) FileUtils.mkdir_p(destination)
It's very unconventional to define a new method inside a method call. File.open(def hello_world(..)) Doesn't make a lot of sense.
until File.exists?( ".osu$" ) == false do
Are you using $ as a way to indicate "filename ends in .osu"? If yes, it does not work like that. This would look for a file that has .osu$ as name.
File.foreach(filename) do |file|
The file parameter is not used in the block that follows, you use file_string.
file_string = File.read('./convert_temp/osz/*.txt$')
You can't read multiple files at once like that. Also, File.foreach above would read the file line by line, so here you are trying to read it again, inside the loop that is reading it already.

Ruby: unexpected ',', expecting keyword_end

Very new to Ruby, unable to see the titular syntax error in this bit of code:
#! /usr/bin/env ruby
require 'sensu-plugin/metric/cli'
class MetricAvailableUpdates < Sensu::Plugin::Metric::CLI::Graphite
option :scheme,
description: 'Metric naming scheme',
long: '--scheme SCHEME',
short: '-s SCHEME',
default: "#{Socket.gethostname}"
def run
# Get the metrics.
output = %x[/usr/lib/update-notifier/apt-check --human-readable]
output_lines = output.split(/(\n)/)
metrics = {}
updates_pattern = " packages can be updated."
updates = output_lines[0].tr(upgrades_pattern, "").to_i
metrics[:available_updates] = updates
security_updates_pattern = " updates are security updates."
security_updates = output_lines[2].tr(security_updates_pattern, "").to_i
metrics[:available_security_updates] = security_updates
# Print them in graphite format.
metrics.each do |k, v|
output [config[:scheme], k].join('.'), v
end
# Done
ok
end
end
I can add the code that precedes this if the syntax error is in fact before this section. Edit: added complete file contents per comment request
The complete error, in case that is useful:
./metrics-available-updates.rb:29: syntax error, unexpected ',', expecting keyword_end
output [config[:scheme], k].join('.'), v
If you play around a bit, you will notice that the syntax error goes away either when you comment out the offending line, or alternatively the line
output = %x[/usr/lib/update-notifier/apt-check --human-readable]
When Ruby parses a file, it needs to guess, whether a symbol denotes a method call, or a variable reference. In this case, output springs into existence as a variable, but further down, you write
output [config[:scheme], k].join('.'), v
which means it suddenly becomes a method call.
I admit that the Ruby lexer should give a more helpful error message....
Add the parentheses
...
metrics.each do |k, v|
output([config[:scheme], k].join('.'), v)
end
...

Bug I cannot identify

I ran this piece of code earlier:
require "awesome_print"
require "rexml/document"
require "debugger"
include REXML
class Scrapper
attr_reader :data
def initialize
file = File.new("./cia-1996.xml")
#data = REXML::Document.new(file)
end
def get_country_inflation
inflation_hash = {}
XPath.match( data, "//country").map { |element|
inflation_hash[element.attributes["name"]] = element.attributes["inflation"].to_i}
nested_array = inflation_hash.to_a
sorted_array = nested_array.sort_by {|country, inflation_value| inflation_value}.reverse
puts "The countries with the highest inflation indexes in 1996 were:"
first_five = sorted_array.first(5)
first_five.each do |item|
puts "#{item[0]}, with an inflation index of #{item[1]}"
end
end
end
end
sample = Scrapper.new
sample.get_country_inflation
After making some edits, I now get error message
economics_challenge.rb:36: syntax error, unexpected keyword_end, expecting end-of-input
Can you please give me pointers as to where the mistake/typo might be (been starring at it for a while now and would appreciate feedback from a new set of eyes).
Thank you so much!
Edit:
so I made the changes suggested but I got more error messages:
economics_challenge.rb:26: syntax error, unexpected tSTRING_DEND, expecting keyword_end
economics_challenge.rb:29: syntax error, unexpected tSTRING_DEND, expecting '}'
...flation_value| inflation_value}.reverse
... ^
economics_challenge.rb:35: syntax error, unexpected keyword_end, expecting '}'
economics_challenge.rb:46: syntax error, unexpected end-of-input, expecting '}'
line 26 refers to the 2nd line in the piece of code below: piece of code (and I think this is where the original problem is):
XPath.match( data, "//country").map do |element|
inflation_hash[element.attributes["name"]] = element.attributes["inflation"].to_i}
end
line 29 is:
sorted_array = nested_array.sort_by {|country, inflation_value| inflation_value}.reverse
I will attempt to fix the error in 29 by calling reverse on sorted array and saving that to a variable.
Line 35 is an end statement and there is no line 46.
Any tips?
Thank you!
2nd Edit:
Wow! I cannot believe I failed to realize that I didn't end many things. I will be sticking to the do andend syntax from now on.
Thank you both for helping me out so much … really appreciate it!
The problem is you have one extra end
As #david-grayson states, had your indentations been correct, you may have spotted it.
This of course, is given the code as you presented it here. It may not be exactly that, though the error message matches the found issue.
Here is the code with indentation, some style changes, and no syntax errors:
require 'awesome_print'
require 'rexml/document'
require 'debugger'
include REXML
class Scrapper
attr_reader :data
def initialize
file = File.new('./cia-1996.xml')
#data = REXML::Document.new(file)
end
def get_country_inflation
inflation_hash = {}
XPath.match(data, '//country').map do |element|
inflation_hash[element.attributes['name']] = element.attributes['inflation'].to_i
end
nested_array = inflation_hash.to_a
sorted_array = nested_array.sort_by do |country, inflation_value|
inflation_value
end.reverse
puts 'The countries with the highest inflation indexes in 1996 were:'
first_five = sorted_array.first(5)
first_five.each do |item|
puts "#{item[0]}, with an inflation index of #{item[1]}"
end
end
end
sample = Scrapper.new
sample.get_country_inflation
Your indentation is messed up starting here:
XPath.match( data, "//country").map { |element|
inflation_hash[element.attributes["name"]] = element.attributes["inflation"].to_i}
nested_array = inflation_hash.to_a
The last line of that excerpt should be unindented by one level because the block you passed to "map" was terminated on the second line by the right bracket.
Try fixing that and everything after it.
Also, here is a tip: always write multi-line blocks using do and end and put the end on its own line. Then you could would be:
XPath.match( data, "//country").map do |element|
inflation_hash[element.attributes["name"]] = element.attributes["inflation"].to_i
end
nested_array = inflation_hash.to_a

Error traces in Erubis

By default, when an an Erubis template raises an error, you get something like this:
(erubis):32:in `evaluate': compile error (SyntaxError)
(erubis):30: syntax error, unexpected ')', expecting ']'
(erubis):32: unterminated string meets end of file
The line numbers refer to the template.
That's all well and good when you just have one template, but I'm batch-processing a bunch of template files. What's the best way to replace the above with a more usable error message, e.g. one that shows the path to the source file instead of (erubis):32?
I'd thought of rescuing, messing around with the exception object, and raising again, but I'm wondering if there's an easier way provided by the Erubis API (or some other one).
You can pass :filename parameter to Erubis.
eruby = Erubis::Eruby.new(string, :filename=>"file.rhtml")
I still suspect there might be a better way to do this using the Erubis API, but here's some code I wrote that seems to work:
def compile_template(template_path, template_str, context, &block)
begin
Erubis::Eruby.new(template_str).evaluate(context, &block)
rescue Exception => exc
trace_normalizer = lambda { |line| line.gsub(/^\(erubis\):/, template_path + ':') }
backtrace = exc.backtrace.collect(&trace_normalizer)
message = trace_normalizer.call(exc.message)
raise exc.class, message, backtrace
end
end

How can I pass a hash into a class_eval'ed method with Ruby 1.8.7?

I'm trying to mock the OpenID handling in my cucumber tests. For this purpose I use the following method:
def set_result_of_openid_authentication(result_type, profile_data = nil)
ActionController::Base.class_eval "
def begin_open_id_authentication(identity_url, options = {})
yield [OpenIdAuthentication::Result.new('#{result_type}'.to_sym), identity_url, #{profile_data}]
end
"
end
# example usage
set_result_of_openid_authentication :successful, 'email' => 'dhofstet#example.com'
This works fine with Ruby 1.9.2, but with Ruby 1.8.7 I get the following compile error:
(eval):5:in `set_result_of_openid_authentication': compile error
(eval):3: syntax error, unexpected tIVAR, expecting kDO or '{' or '('
...identity_url, emaildhofstet#example.com]
For some reason the hash is not preserved... Is there some workaround to make it work with both Rubies?
Thanks.
It looks like the problem is that inside your class_eval the interpolated string #{profile_data} is coming through as emaildhofstet#example.com which is the to_s representation of a Hash in 1.8.7.
If you replace this with #{profile_data.inspect} then it should come come through as {'email' => 'dhofstet#example.com'} as required.

Resources