Reputation: 1993
Basically question is about ruby syntax
class Person < ActiveRecord::Base
validates :name, presence: true #no error
end
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 ^
Upvotes: 0
Views: 96
Reputation: 879
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.
Upvotes: 2
Reputation: 6126
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.
Upvotes: 3