Optional parens in Ruby for method with uppercase start letter?
This is just part of Ruby's ambiguity resolution.
In Ruby, methods and variables live in different namespaces, therefore there can be methods and variables (or constants) with the same name. This means that, when using them, there needs to be some way to distinguish them. In general, that's not a problem: messages have receivers, variables don't. Messages have arguments, variables don't. Variables are assigned to, messages aren't.
The only problem is when you have no receiver, no argument and no assignment. Then, Ruby cannot tell the difference between a receiverless message send without arguments and a variable. So, it has to make up some arbitrary rules, and those rules are basically:
- for an ambiguous token starting with a lowercase letter, prefer to interpret it as a message send, unless you positively know it is a variable (i.e. the parser (not(!) the interpreter) has seen an assignment before)
- for an ambiguous token starting with an uppercase letter, prefer to interpret it as a constant
Note that for a message send with arguments (even if the argument list is empty), there is no ambiguity, which is why your third example works.
test()
: obviously a message send, no ambiguity heretest
: might be a message send or a variable; resolution rules say it is a message sendTest()
: obviously a message send, no ambiguity hereself.Test
: also obviously a message send, no ambiguity hereTest
: might be a message send or a constant; resolution rules say it is a constant
Note that those rules are a little bit subtle, for example here:
if false
foo = 'This will never get executed'
end
foo # still this will get interpreted as a variable
The rules say that whether an ambiguous token gets interpreted as a variable or a message send is determined by the parser and not the interpreter. So, because the parser has seen foo = whatever
, it tags foo
as a variable, even though the code will never get executed and foo
will evaluate to nil
as all uninitialized variables in Ruby do.
TL;DR summary: you're SOL.
What you could do is override const_missing
to translate into a message send. Something like this:
class DemoClass
def test; puts "output from test" end
def Test; puts "output from Test" end
def run
puts "Calling 'test'"
test()
puts "Calling 'test'"
test
puts "Calling 'Test()'"
Test()
puts "Calling 'Test'"
Test
end
def self.const_missing(const)
send const.downcase
end
end
demo = DemoClass.new
demo.run
Except this obviously won't work, since const_missing
is defined on DemoClass
and thus, when const_missing
is run, self
is DemoClass
which means that it tries to call DemoClass.test
when it should be calling DemoClass#test
via demo.test
.
I don't know how to easily solve this.
How does ruby allow a method and a Class with the same name?
Methods and variables live in different namespaces. So, you can have both a method and a variable (or in this case a constant) with the same name. However, when using them, Ruby needs to be able to distinguish between them. In general, that's not a problem: messages have receivers, variables don't. Messages have arguments, variables don't. Variables are assigned to, messages aren't.
The only problem is when you have no receiver, no argument and no assignment. Then, Ruby cannot tell the difference between a receiverless message send without arguments and a variable. So, it has to make up some arbitrary rules, and those rules are basically:
- for an ambiguous token starting with a lowercase letter, prefer to interpret it as a message send, unless you positively know it is a variable (i.e. the parser (not(!) the interpreter) has seen an assignment before)
- for an ambiguous token starting with an uppercase letter, prefer to interpret it as a constant
Note that for a message send with arguments (even if the argument list is empty), there is no ambiguity.
test()
: obviously a message send, no ambiguity heretest
: might be a message send or a variable; resolution rules say it is a message send (unless there has been an assignment totest
before)Test()
: obviously a message send, no ambiguity hereself.Test
: also obviously a message send, no ambiguity hereTest
: might be a message send or a constant; resolution rules say it is a constant
uninitialized constant My_Class::Accessor (NameError) - uppercase accessor
In Ruby, any name that starts with an upper case character is a constant. This means that when the interpreter sees your #to_s
method, it will look for a constant named A
, not for a method.
You can read more about it here: http://ruby-doc.org/docs/ProgrammingRuby/html/language.html#S3
Use ActiveRecord's to_xml method, but camelize with first letter as lowercase
Just replace true
with :lower
:
{ "hello_world" => 1 }.to_xml(:camelize => :lower)
#=> "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<hash>\n <helloWorld type=\"integer\">1</helloWorld>\n</hash>\n"
What are the uppercase and lowercase rules of ruby method name?
By convention, things that start with uppercase letters are constants. When you invoke SayHi
, you're telling Ruby to look for a constant with this name. Of course, there isn't one, so it fails.
If you want to invoke the method, you'll need to add a pair of parentheses. For example,
def S
puts "shazam!"
end
S #=> NameError: uninitialized constant S
S() #=> "shazam!"
Inside of a class, the resolution rules are a little different. Let's define a simple class with a constant and a method named to look like a constant:
irb(main):001:0> class C
irb(main):002:1> A = "x"
irb(main):003:1> def B
irb(main):004:2> puts "B() invoked"
irb(main):005:2> end
irb(main):006:1> end
=> nil
Now, A
is certainly a constant. But what about B
?
irb(main):008:0> C.const_defined?("A")
=> true # A is a constant!
irb(main):009:0> C.const_defined?("B")
=> false # B looks like a constant but isn't, because we
# used "def" to create it. "def" is for methods,
# not constants.
So it isn't a constant, just a method with that name. When we try to access B
from an instance of C
, now Ruby's looking for a method:
irb(main):011:0> C.new.B
B() invoked
=> nil
If we wanted to access a constant of C
instead, we use the scope qualifier ::
:
irb(main):012:0> C::A
=> "x"
What are the restrictions for method names in Ruby?
Method names in Ruby may contain upper-case and lower-case letters, numbers, underscores _
and the punctation signs !
, ?
, =
.
A method name can't begin with a number, and the characters !
, ?
and =
can only appear at the end.
Non-ASCII characters can be used in a method name, but this can lead to very confusing situations and should not be common practice.
It's good practice, while not mandatory, to start the method name with a lower-case character, because names that start with capital letters are constants in Ruby. It's still possible to use a constant name for a method, but you won't be able to invoke it without parentheses, because the interpeter will look-up for the name as a constant:
def Capital
nil
end
Capital # NameError: uninitialized constant Capital
Capital() # => nil
Some very widely and consistently used conventions when defining method names are:
Method names are full down-case, with underscores
_
as separators for words into the name (e.g.Math::sqrt
,Array#each_index
, ...).Predicates have a question mark
?
as last character (e.g.Array#empty?
,Hash#has_key?
, ...). While predicates usually return boolean values, this is not always the case: these methods just need to returnnil
orfalse
if the predicate evaluates to false, any other value otherwise (e.g.File::size?
returnsnil
if the file does not exist, the size of the file as anInteger
otherwise).Methods that modify the state of the object on which they are invoked, or that have an unusual behavior have an exclamation mark
!
as last character; this methods are sometimes called mutators because they usually are destructive or in-place versions of other methods (e.g.Array#sort!
,Array#slice!
, ...).Setters have an equal sign
=
as last character (e.g.Array#[]=
, ...); the Ruby interpeter offers syntactic sugar for invokation of setter methods:a = [4, 5, 6]
a[0] = 3 # Shorthand for a.[]=(0, 3)
Ruby also allows to define operators using the operator symbol as the method name:
╔═══════════════════════════╦═════════════════════════════════════════════╦═══════╗
║ Operators (by precedence) ║ Operations ║ Arity ║
╠═══════════════════════════╬═════════════════════════════════════════════╬═══════╣
║ ! ~ + ║ Boolean NOT, bitwise complement, unary plus ║ 1 ║
║ ║ (define with method name +@, Ruby 1.9+) ║ ║
║ ║ ║ ║
║ ** ║ Exponentiation ║ 2 ║
║ ║ ║ ║
║ - ║ Unary minus (define with method name -@) ║ 1 ║
║ ║ ║ ║
║ * / % ║ Multiplication, division, modulo ║ 2 ║
║ ║ ║ ║
║ + - ║ Addition, subtraction ║ 2 ║
║ ║ ║ ║
║ << >> ║ Bitwise shift ║ 2 ║
║ ║ ║ ║
║ & ║ Bitwise AND ║ 2 ║
║ ║ ║ ║
║ | ^ ║ Bitwise OR, Bitwise XOR ║ 2 ║
║ ║ ║ ║
║ < <= => > ║ Ordering ║ 2 ║
║ ║ ║ ║
║ == === != =~ !~ <=> ║ Equality, pattern matching, comparison ║ 2 ║
╚═══════════════════════════╩═════════════════════════════════════════════╩═══════╝
Unary operator methods are passed no arguments; binary operator methods are passed an argument, and operate on it and on self
.
It's important to adhere strictly to the arity of the operators; while it is possible to define operator methods with a different arity (e.g. a +
method that takes two arguments), Ruby would not allow you to call the method with operator syntax (it would however work with dot syntax).
It's good practice to adhere to the original semantics of the operators as much as possible: it should be intuitive to someone who knows the original meaning of the operator how it works with user defined classes.
The language also offers syntactic sugar for the special, non-operator ,[]
method that is normally used for accessing array and hash values. The []
method can be defined with arbitrary arity.
For every binary operator in the table, except ordering, equality, comparison and pattern matching, Ruby also offers shorthand for abbreviated assignment (e.g. x += y
expands to x = x + y
); you can't define them as methods, but you can alter their behavior defining the operators on which they're based.
None of these characters can be used inside normal method names (e.g. do&print
or start-up
are not valid method names).
Ruby function for putting string in parentheses
I would use string interpolation:
str = " ( #{str} ) "
Some other options might be:
str = ' ( ' + str + ' ) '
str = [' ( ', str, ' ) '].join
Method and variable name is the same
Try this:
puts hello()
how to group a special character and a letter in regex in ruby?
You may use
/\AST[A-Z]?(#{A_VAL})(?:-?T)?\z/
Details
\A
- start of stringST
- anST
substring[A-Z]?
- an optional ASCII letter(#{A_VAL})
- Group 1 (if there is a single alternative, just one string, and you do not need this value later, you may omit the capturing parentheses): a pattern insideA_VAL
variable(?:-?T)?
- an optional non-capturing group that matches an optional-
and an obligatoryT
(i.e. it matches-T
orT
1 or 0 times)\z
- end of string.
Related Topics
How to Get the Current Test Filename from Rspec
Encryption-Decryption in Rails
Homebrew Install Ruby Keg-Only Can't Find Gem
Capistrano 3 Change Ssh_Options Inside Task
Symbol#To_Proc with Custom Methods
How to Decode Q-Encoded Strings in Ruby
Can't Run Bundle Update on Windows
Time Gt Query Not Working with Mongoid and Ruby on Rails
Optional Parens in Ruby for Method with Uppercase Start Letter
How to Use Same Browser Window for Automated Test Using Selenium-Webdriver (Ruby)
Install Cocoapods Failed on MAC
Can't Convert String into Integer in Ruby/Ruby-On-Rails
How to Format a Date to Mm/Dd/Yyyy in Ruby
What Order Do Before Filters Occur In
What Does the Term "Vendoring" or "To Vendor" Mean for Ruby on Rails