I was reading the source code of a gem "activerecord-postgres-earthdistance".
While running the migration script, it threw an error on the following method
def order_by_distance lat, lng, order: "ASC"
It gave an error for order: "ASC"
syntax error, unexpected tLABEL
Isn't this valid Ruby syntax?
Ruby 2.0 supports keywords arguments
[5] pry(main)> def bar(a: "name", b: "fem"); puts a,b end
[6] pry(main)> bar(a: "John", b: "Male")
John
Male
[7] pry(main)> bar("John", "Male")
ArgumentError: wrong number of arguments (2 for 0)
from (pry):5:in `bar'
However the above is not valid in 1.9 see below:
ruby 1.9.3p448 (2013-06-27 revision 41675) [x86_64-darwin12.4.0]
[2] pry(main)> def bar(a: "name", b: "fem"); puts a,b end
SyntaxError: unexpected ',', expecting $end
def bar(a: "name", b: "fem"); puts a,b end
^
[2] pry(main)> def bar(a: "name"); puts a end
SyntaxError: unexpected ')', expecting $end
def bar(a: "name"); puts a end
^
For better understanding you can read here and here
def order_by_distance(lat, lng, hash={})
puts hash[:order]
end
=> order_by_distance(lat, lng, order: "ASC")
=> "ASC"
use hash arguments in ruby
Related
Basically question is about ruby syntax
class Person < ActiveRecord::Base
validates :name, presence: true #no error
end
Code Source
My 2 Questions
1
To me this code validates :name, presence: true looks a like call to a method.
How can we call a method inside class body, outside any method? I think its not possible in oops.
2
Why I am getting error in these two variations
validates (:name , presence: true) #error
or
validates (:name , {presence: true}) #error
I have added parentheses to method call, as its allowed in ruby.
First parameter is symbol and 2nd parameter is hash.
In first case I have not added curly braces to hash, as I read that if last parameter is hash you can leave curly braces, In second code I have explicitly added curly braces but still got error.
Can anyone explain this syntax.
Thanks
Edit 1
Errors
In first I am getting
product.rb:8: syntax error, unexpected ',', expecting ')' validates (:name , presence: true) # error ^
In Second I am getting
product.rb:10: syntax error, unexpected ',', expecting ')' validates (:title , {presence: true}) # error ^
1: In ruby you can call a method when defining a class:
% irb
2.2.2 :001 > class Dummy
2.2.2 :002?> puts "Making a class..."
2.2.2 :003?> def hello
2.2.2 :004?> puts "Hello"
2.2.2 :005?> end
2.2.2 :006?> end
Making a class...
=> :hello
2.2.2 :007 > d = Dummy.new
=> #<Dummy:0x000000009ebbf0>
2.2.2 :008 > d.hello
Hello
=> nil
So that's exactly what's going on.
2: You get an error because you have a space between the method name and the argument list:
% irb
2.2.3 :001 > def func(*splat)
2.2.3 :002?> puts splat.inspect
2.2.3 :003?> end
=> :func
2.2.3 :004 > func(:test, :another => :test)
[:test, {:another=>:test}]
=> nil
2.2.3 :005 > func (:test)
[:test]
=> nil
2.2.3 :006 > func (:test, :another => :test)
SyntaxError: (irb):6: syntax error, unexpected ',', expecting ')'
func (:test, :another => :test)
^
from /home/haraldei/.rvm/rubies/ruby-2.2.3/bin/irb:11:in `<main>'
The second example above, where I'm passing just one arg works because you can enclose any valid expression in parenthesis. This is not the same as an argument list. So the expression:
(:test, :another => :test)
is not a valid expression, but the parser tries to pass it as one parenthesized argument to the method.
So to summarize, both your argument lists are correct, if you remove the space between them and the function name.
The answer to your first question: "Yes it is a method" and this is also somehow the answer to your second question.
The answer to your second question is "remove the space between validates and (". When having validates (...) it will throw
syntax error, unexpected ',', expecting ')' (SyntaxError)
validates (:name , presence: true)
validates is a method, and if using parentheses you mustn't use spaces.
I am simply trying to get the average two columns of a colon separated file. What am I doing wrong here?
/experimental/1$ cat list.csv
a:7:98:East
b:2:34:East
c:10:94:North
d:7:43:West
e:6:88:South
/experimental/1$ cat play.rb
#!/usr/bin/env ruby
require 'csv'
average_spending = Array.new
CSV.foreach('list.csv', converters: :numeric, { :col_sep => ':' }) do |row|
average_spending << row[2] / row[1]
end
/experimental/1$ ./play.rb
./play.rb:5: syntax error, unexpected ')', expecting tASSOC
... :numeric, { :col_sep => ':' }) do |row|
... ^
./play.rb:7: syntax error, unexpected keyword_end, expecting $end
Thank you in advance,
~Chris
CSV.foreach accepts 2 arguments and block(you are trying to pass 3), use
CSV.foreach('list.csv', { converters: :numeric, col_sep: ':' }) {...}
I am getting TypeError: can't convert String into Integer, I found duplicate answer too, but I am facing this error for 'pack'.
Other confusion is, it is working fine with ruby 1.8.7, not with ruby 1.9.3, here is the code, I am using jruby1.7.2
irb(main):003:0> length=nil
=> nil
irb(main):004:0> token_string ||= ["A".."Z","a".."z","0".."9"].collect { |r| r.to_a }.join + %q(!$:*)
=> "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!$:*"
irb(main):005:0> token = (0..(length ? length : 60)).collect { token_string[rand( token_string.size)]}.pack("c*")
TypeError: can't convert String into Integer
from (irb):5:in `pack'
from (irb):5
from /home/appandya/.rvm/rubies/ruby-1.9.3-p374/bin/irb:13:in `<main>'
irb(main):006:0>
Any Idea?
string[x] in Ruby 1.8 gives you a Fixnum (the character code) and in 1.9 it gives you a single character string.
Array#pack turns an array into a binary sequence. The "c*" template to pack converts an array of Ruby integers into a stream of 8-bit signed words.
Here are the solutions, those comes from the Google Groups
1.
Background
>> %w(a b c).pack('*c')
TypeError: can't convert String into Integer
from (irb):1:in `pack'
from (irb):1
from /usr/bin/irb:12:in `<main>'
>> [1, 2, 3].pack('*c')
=> "\x01"
>> %w(a b c).map(&:ord).pack('*c')
=> "a"
Solution
irb(main):001:0> length=nil
=> nil
irb(main):002:0> token_string ||= ["A".."Z","a".."z","0".."9"].collect { |r| r.to_a }.join + %q(!$:*)
=> "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!$:*"
irb(main):003:0> (0..(length ? length : 60)).collect { token_string[rand( token_string.size)]}.map(&:ord).pack("c*")
=> "rd!:!LcxU3ON57*t2s520v*zvvdflSNAgU6uq14SiD00VUDlm9:4:tJz5Ri5o"
irb(main):004:0>
2.
The return type of String's [] function was Fixnum in 1.8 but is String in 1.9:
>JRUBY_OPTS=--1.9 ruby -e "puts 'a'[0].class"
String
>JRUBY_OPTS=--1.8 ruby -e "puts 'a'[0].class"
Fixnum
JRuby 1.7.x defaults to acting like Ruby 1.9.3. You need to set JRUBY_OPTS.
3.
try join instead of pack
irb(main):004:0> length=nil
=> nil
irb(main):005:0> token_string ||= ["A".."Z","a".."z","0".."9"].collect { |r| r.to_a }.join + %q(!$:*)
=> "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!$:*"
irb(main):006:0> token = (0..(length ? length : 60)).collect { token_string[rand( token_string.size)]}.join("c*")
=> "Fc*Dc*1c*6c*ac*Kc*Tc*Qc*Hc*jc*Ec*Kc*kc*zc*sc*3c*ic*hc*kc*wc**c*Wc*$c*Kc*Ic*Uc*Cc*bc*Pc*1c*!c*mc*Bc*lc*dc*ic*Dc*sc*Ac*Bc*nc*Kc*mc*Lc*oc*Zc*Xc*jc*6c*2c*Uc*ec*Yc*Dc*vc*Ic*Uc*5c*Zc*3c*o"
irb(main):007:0>
4.
if you're just trying to make a string of random characters that are 8-bit clean you may want to look at Random#bytes and something like Base64.encode64.
5.
active_support/secure_random also has a nice API for these things
I would recommend you take a look at: Array Method Pack, essentially the .pack("c") expects the elements of the array to be integers. You could try .pack("a*")
Use token = (0..(length ? length : 60)).collect { token_string[rand( token_string.size)]}.pack("a"*61)
You get the same result. I am using 61 because, going from 0..60 has 61 elements.
I have the following controller code:
def index
#profiles = Profile.where("(first_name || ' ' || last_name) ILIKE ?", "%#{params[:q]}%")
#autolist = []
#profiles.each do |profile|
user = User.find_by_id(profile.user_id)
#autolist.concat([{"id",profile.id,"name",profile.first_name+" "+profile.last_name,"email",user.email}])
end
respond_to do |format|
format.html # index.html.erb
format.json { render :json => #autolist }
end
end
It works in my local environment, but crashes my app. Specifically this line: #autolist.concat([{"id",profile.id,"name",profile.first_name+" "+profile.last_name,"email",user.email}])
Any ideas?
I have a feeling it has to do with my local env using ruby 1.8.7 and the heroku app running 1.9.2
This works in 1.8.7:
>> h = {"id", 6}
=> {"id"=>6}
but not in 1.9.2:
>> h = {"id",6}
SyntaxError: (irb):4: syntax error, unexpected ',', expecting tASSOC
h = {"id",6}
^
from /Users/mu/Developer/.rvm/rubies/ruby-1.9.2-p180/bin/irb:16:in `<main>'
The rocket notation will serve you better:
#autolist.concat([{ "id" => profile.id, "name" => profile.first_name + " " + profile.last_name, "email" => user.email}])
I can't find any mention of this change in the 1.9.1 or 1.9.2 release notes and this is actually the first time I've seen the {'a', b} syntax for a Ruby Hash. Perhaps that notation was a deprecated feature that finally went away.
BTW, developing on 1.8.7 and deploying on 1.9.2 isn't the best idea.
My website works fine on my local mashine but crashes on heroku.
Here is my heroku log: http://pastie.org/private/ligfhv4tjqmodclkwxc21q
Relevant log section:
[36m2011-12-01T19:42:53+00:00 app[web.1]:←[0m
/app/.bundle/gems/ruby/1.8/gems/a
ctivesupport-3.0.3/lib/active_support/dependencies.rb:239:in
`require': /app/app /helpers/kategoris_helper.rb:2: syntax error,
unexpected kEND, expecting $end (S yntaxError)
My stack is bamboo-ree 1.8.7
I think it is to do with this helper, but are not sure:
module KategorisHelper
def sortkat(column, title = nil)
title ||= column.titleize
css_class = column == sort_column ? "current #{sort_direction}" : nil
direction = column == sort_column && sort_direction == "ASC" ? "DESC" : "ASC"
link_to title, params.merge(:sort => column, :direction => direction, :page => nil), {:class => css_class}
end
end
Well, the error message basically means that there's an end too much (syntax error, unexpected kEND, expecting $end, a missing end is syntax error, unexpected $end, expecting kEND). ruby -c doesn't complain about your helper, did you copy the entire code?