Calling methods on arrays with dot notation


#1

Hello,

I want to use the alphabetize method on numbers array with dot syntax/notation (I’m not sure what exactly its called)

I know I can use it as:

puts alphabetize(numbers)

but I want to be able use it as this as well:

puts numbers.alphabetize

I know this is possible for strings. I tried using it on the capitalizing exercise.

When I try the latter, the output is :
undefined method `alphabetize’ for [0, 1, 1, 2, 3, 3, 4, 5, 6, 6, 7, 7, 9, 32]:Array

I searched the web and it seems I can use arrays as any parameter for methods.


def alphabetize (array, rev = false)
  array.sort!
 
  if rev != true
  	return array
  else
    array.reverse!
  end
  
end

numbers = [1,2,4,5,1,6,7,3,32,6,7,3,0,9]


puts numbers.alphabetize

This code returns the error message above.

What am I missing here?

Any help would be very much appreciated as I can’t really find on the web an enough-technical answer to my question which matches my skill level.


#2

In order to do what you are after there needs to be a class of which alphabetize is a method. With a class we can create an instance that inherits the method.

class List
  def initialize(data)
    @data = data
  end
  def alphabetize
    @data.sort
  end
end
ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-linux]
 > 
=> :alphabetize
 > numbers = List.new([7,4,9,2,7,5,1,9,8,4,6,9,5])
=> #<List:0x0055c289db7f80 @data=[7, 4, 9, 2, 7, 5, 1, 9, 8, 4, 6, 9, 5]>
 > numbers.alphabetize()
=> [1, 2, 4, 4, 5, 5, 6, 7, 7, 8, 9, 9, 9]   
 > letters = List.new(['a','j','e','i','x','b','t','q','m','d','p'])  
..   
=> #<List:0x0055c289db53c0 @data=["a", "j", "e", "i", "x", "b", "t", "q", "m", "d", "p"]>
 > letters.alphabetize()
=> ["a", "b", "d", "e", "i", "j", "m", "p", "q", "t", "x"]   

#3

Thank you for the clarification mtf.

I understand now. I will study classes more.
Most of the exercises failed with dot notation as per you explanation but one worked.

Here is the code:

# method that capitalizes a word
def capitalize(string) 
  puts "#{string[0].upcase}#{string[1..-1]}"
end

capitalize("ryan") # prints "Ryan"
capitalize("jane") # prints "Jane"

# block that capitalizes each string in the array
["ryan", "jane"].each {|string| puts "#{string[0].upcase}#{string[1..-1]}"} # prints "Ryan", then "Jane"

puts "aa".capitalize

Is this because the method was defined well?

If we are to write the code for sorting algorithm such as it is for capitalizing in the example above?


#4

It is because of where it is defined. Methods that start with a dot (always following an object) are defined in the class that the object is an instance of. Above, .each is a method of the Array class (all iterable classes have this method), and .upcase is a method of the String class.

Methods that are defined directly, are standalone functions that have no class tied to them. However, they may not return the correct values (or may raise an exception) if the expected input is not given. Try passing your above function an array or a hash, or even a number or boolean primitive.

 > capitalize(1234)
undefined method `upcase' for 0:Fixnum
(repl):3:in `capitalize'
(repl):1:in `<main>'
 > capitalize([1,2,3,5])
undefined method `upcase' for 1:Fixnum
(repl):3:in `capitalize'
(repl):1:in `<main>'
 > capitalize({:a=>1,:b=>2,:c=>3,:d=>4})
undefined method `upcase' for nil:NilClass
(repl):3:in `capitalize'
(repl):1:in `<main>'
 > capitalize(true)
undefined method `[]' for true:TrueClass
(repl):3:in `capitalize'
(repl):1:in `<main>'
 > capitalize(['a', 'b', 'c', 'd'])
A["b", "c", "d"]
=> nil   
 >

As we can see, all the foreign objects raise expceptions. Note the last input. It stripped the first element, and capitalized it. Not an expected return value, though easily explained.

That works because the String class has that built-in method.


#5

Thank you so much for the information!


#6

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.