In Settingslogic fork allowing array as source, in ruby 1.8.7 everything is working, but in ruby 1.9.2 there is an error. The problem is within this part of the code:
self.class.class_eval <<-EndEval
def #{key}
return ##{key} if ##{key}
raise MissingSetting, "Missing setting '#{key}' in #{#section}" unless has_key? '#{key}'
value = fetch('#{key}')
##{key} = value.is_a?(Hash) ? self.class.new(value, "'#{key}' section in #{#section}") : value
end
EndEval
#section == ["path_to_yml_file1", "path_to_yml_file2",...]
Looks like #{} is evaluated in some strange way, "#{#section}" seems to be an array, not a string. Can anybody explain this?
Error trace:
#section == ["User/project/config/defaults.yml", "/Users/project/config/development.yml"]
ruby-1.9.2-p290 :001 > Settings.keys
SyntaxError: (eval):3: syntax error, unexpected tSTRING_BEG, expecting keyword_end
...project/config/defaults.yml", "/Users/project...
... ^
(eval):3: syntax error, unexpected tSTRING_BEG, expecting keyword_end
...project/config/development.yml"]" unless has_key? 'front'
... ^
(eval):5: syntax error, unexpected tSTRING_BEG, expecting ')'
...project/config/defaults.yml", "/Users/project...
... ^
(eval):5: syntax error, unexpected tSTRING_BEG, expecting keyword_end
...project/config/development.yml"]") : value
... ^
(eval):5: syntax error, unexpected ')', expecting keyword_end
...project/config/development.yml"]") : value
... ^
from .../settingslogic-3b5d7d9cc319/lib/settingslogic.rb:198:in `class_eval'
Thanks for any help
You've made a fork from main settingslogic. At that time it didn't support array as source, but now it does. Try to use main settingslogic repository.
Your error now related to this string:
raise MissingSetting,
"Missing setting '#{key}' in #{#section}" unless has_key? '#{key}'
because in case of using array instead of string
./settings.yml
you get something like this:
[\"./settings.yml\"]
The same happens with ##{key} assignment below. In main repository this code replaced to string concatenation.
Try self.class_eval or even without self, no need to get the name of class and self automatically assign to current object i.e. your class.
Related
I have this very simple piece of code (using Ruby 3)
def eat(main, dessert*)
if dessert.empty?
puts "I eat #{main}"
else
puts "I eat #{main} than #{dessert}."
end
end
Wher I run eat("mushrooms") that provokes errors:
argu.rb:1: syntax error, unexpected '*', expecting ')'
def manger(plat, dessert*)
argu.rb:7: syntax error, unexpected `end', expecting end-of-input
I don't see why.
Splat operator should put before parameters so your signature should be
def eat(main, *dessert)
Not sure where you got the idea from using dessert*, but you could define your method as
def eat(main, dessert = [])
to provide a default argument (of course it must be one which can respond to empty?).
Of course it is up to you to justify, why "main" can be anything (i.e. a String), but dessert must be a collection. I would test for dessert as
if dessert.nil?
and hence provide nil as default value for the dessert.
I was working with Java for a few months and am transitioning back to Ruby now. I am getting a weird error from the following code:
def count_divisors
divisor_hash = {}
25.times do |i|
divisor_hash[i] = find_dividends(i)
end
puts divisor_hash
end
def find_dividends(i)
count = 0
1000.times do |k|
if i % ( k + 1 ) == 0
count++
end
end
count
end
count_divisors()
This code is generating the following error:
test.rb:14: syntax error, unexpected keyword_end
test.rb:19: syntax error, unexpected end-of-input, expecting keyword_end
This error does not occur when I remove the if statement. I am not sure why. I know every if statement needs an end statement, for some reason it seems upset by the placement of that end statement though.
Change the count++ to count += 1 Ruby does not support incremental operator.
When I use a shortened if/else statement with Sinatra commands, I receive a syntax error:
request.cookies['blog'].nil? ? erb :blog : redirect '/done'
Returns this error:
/home/sinatra/ptt/ptt.rb:107: syntax error, unexpected tSTRING_BEG, expecting keyword_do or '{' or '(' request.cookies['blog'].nil? ? "erb :blog" : redirect '/done' ^
Both of the statements produce errors when by themselves (without Sinatra code as the other statement).
Is this a Sinatra problem or is the syntax incorrect?
The error does not occur when the true/false statements are plain Ruby:
request.cookies['blog'].nil? ? foo = 1 : bar = 2
I think Ruby can't decide what is a method call and what belongs to the if statement. Try this:
request.cookies['blog'].nil? ? erb(:blog) : redirect('/done')
This question already has answers here:
Unexpected keyword_end error, yet syntax seems fine
(2 answers)
Closed 8 years ago.
I seem to be getting an error for this block, and I'm not quite sure why. If I remove the break and the counter it works, but if I add them I get this error:
Error:
/home/rails_apps/Twitter_App/app/controllers/dashboard_controller.rb:133: syntax error, unexpected keyword_end
/home/rails_apps/Twitter_App/app/controllers/dashboard_controller.rb:145: syntax error, unexpected end-of-input, expecting keyword_end
Code:
#followers2.each do |follow|
#followers3 << Twitter.user(follow)
break if i >10
i++
end
I was an idiot, I totally forgot that Ruby doesn't make use of the increment operator....doh!
Changed from:
#followers2.each do |follow|
#followers3 << Twitter.user(follow)
break if i >10
i++
end
To this:
#followers2.each do |follow|
#followers3 << Twitter.user(follow)
break if i >10
i+=1
end
On the last line you are using the binary infix + operator but you never provide the second operand. Ruby is expecting the operand on the next line (whitespace is allowed between an operator and its operands) but instead it hits the end keyword. You need to provide the second operand.
I like method parameters enclosed in parenthesis, this is some Pascal nostalgia. When cleaning up code, if I find a method parameters without it I enclose them immediately.
Today it caused my working code throwing errors although my syntax looks okay according to the documentation.
Kernel.raise's documentation has this format:
(Object) raise(exception[, string [, array]])
These are all working:
> raise TypeError
TypeError: TypeError
> raise (TypeError)
TypeError: TypeError
> raise "Error message"
RuntimeError: Error message
> raise ("Error message")
RuntimeError: Error message
But the enclosed version of the next throws syntax error:
> raise TypeError, "Error message"
TypeError: Error message
> raise (TypeError, "Error message")
SyntaxError: unexpected ')', expecting $end
I can live without it, I just want to know why this ends with an error.
You probably already know that in idiomatic Ruby one would never insert a space between the end of a method and an argument list in parenthesis. Some style guides explicitly forbid it.
There's a pragmatic reason too.
1.9.2-p290 > def concat(a, b)
1.9.2-p290 > a + b
1.9.2-p290 > end
1.9.2-p290 > concat 'foo', 'bar'
=> "foobar"
1.9.2-p290 > concat('foo', 'bar')
=> "foobar"
1.9.2-p290 > concat ('foo', 'bar')
SyntaxError: (irb):27: syntax error, unexpected ',', expecting ')'
You'll encounter errors calling any method this way, not just Kernel.raise.
I'm not familiar with Ruby internals, but I would imagine the reason for this is that when a space precedes the argument list, Ruby is expecting the "no-parens" style. So of course this works:
1.9.2-p290 :035 > concat ("bar"), ("foo")
=> "barfoo"
Presumably Ruby is trying to evaluate the contents of each parenthesized expression before passing the result to the method. I'd speculate that writing raise (TypeError, "Error message") is asking Ruby to evaluate just TypeError, "Error message", which of course fails.
Parentheses are used for expression grouping and precedence override in Ruby. So, when you say
foo (bar, baz)
You are sending the message :foo with a single argument which is the result of evaluating the expression bar, baz. And bar, baz is not a valid expression, therefore you get a SyntaxError.
foo (bar)
works, because bar is a valid expression.
foo (if bar then baz else quux end)
would work, too.
If you want Ruby to interpret parentheses not for expression grouping but for passing multiple arguments along with a message send, the opening parenthesis needs to directly follow the message selector:
foo(bar, baz)
This has nothing to do with Kernel#raise, BTW. You cannot change the syntax for message sends in Ruby (in fact, you cannot change any syntax in Ruby), therefore whatever is true for Kernel#raise must also be true for every other method.