Optional Parens in Ruby for Method with Uppercase Start Letter

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 here
  • test: might be a message send or a variable; resolution rules say it is a message send
  • Test(): obviously a message send, no ambiguity here
  • self.Test: also obviously a message send, no ambiguity here
  • Test: 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 here
  • test: might be a message send or a variable; resolution rules say it is a message send (unless there has been an assignment to test before)
  • Test(): obviously a message send, no ambiguity here
  • self.Test: also obviously a message send, no ambiguity here
  • Test: 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:

  1. Method names are full down-case, with underscores _ as separators for words into the name (e.g. Math::sqrt, Array#each_index, ...).

  2. 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 return nil or false if the predicate evaluates to false, any other value otherwise (e.g. File::size? returns nil if the file does not exist, the size of the file as an Integer otherwise).

  3. 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!, ...).

  4. 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 string
  • ST - an ST 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 inside A_VAL variable
  • (?:-?T)? - an optional non-capturing group that matches an optional - and an obligatory T (i.e. it matches -T or T 1 or 0 times)
  • \z - end of string.


Related Topics



Leave a reply



Submit