Книга: Metaprogramming Ruby 2
Назад: Appendix 1: Common Idioms
Дальше: Nil Guards

Mimic Methods

Much of Ruby’s appeal comes from its flexible syntax. You can find an example of this flexiblity even in the most basic program:

 
puts ​'Hello, world'

Newcomers to Ruby often mistake puts for a language keyword, when it’s actually a method. People usually leave out the parentheses when calling puts, so it doesn’t look like a method. Reinsert the parentheses, and the nature of puts becomes obvious:

 
puts(​'Hello, world'​)

Thanks to disguised method calls such as this one, Ruby manages to provide many useful function-like methods while keeping the core of the language relatively small and uncluttered.

This simple idea of dropping parentheses from method calls is used quite often by expert coders. Sometimes you’ll want to keep the parentheses because they make a method’s nature obvious—or maybe because the parser requires the parentheses to make sense of a complex line of code. Other times, you’ll want to drop the parentheses to make the code cleaner or to make a method look like a keyword, as is the case with puts.

For another example of flexible syntax, think of object attributes, which are actually methods in disguise:

 
class​ C
 
def​ my_attribute=(value)
 
@p = value
 
end
 
 
def​ my_attribute
 
@p
 
end
 
end
 
 
obj = C.new
 
obj.my_attribute = ​'some value'
 
obj.my_attribute ​# => "some value"

Writing obj.my_attribute = ’some value’ is the same as writing obj.my_attribute=(’some value’), but it looks cleaner.

What should we call disguised methods such as my_attribute and my_attribute=? Let’s take a cue from zoology: an animal that disguises itself as another species is said to employ “mimicry.” Following that pattern, a method call that disguises itself as something else, such as puts or obj.my_attribute=, can be called a Spell: .

Mimic Methods are a very simple concept, but the more you look into Ruby, the more you find creative uses for them. For example, access modifiers such as private and protected are Mimic Methods, as are Class Macros () such as attr_reader. Popular libraries provide further examples. Here is one such example.

The Camping Example

The following snippet of code comes from an application written with the Camping web framework. It binds the /help URL to a specific controller action:

 
class​ Help < R ​'/help'
 
def​ get
 
# rendering for HTTP GET...

Class Help seems to inherit from a class named R. But what’s that quirky little string right after R? You might assume that Ruby would simply refuse this syntax, until you realize that R is actually a Mimic Method that takes a string and returns an instance of Class. That is the class that Help actually inherits from. (If the notion of a method returning a class sounds strange to you, consider that Ruby classes are just objects, as you can read in Chapter 2, .)

Thanks to creative tricks such as this one, Camping feels less like a Ruby web framework and more like a domain-specific language for web development. In general, this is a good thing, as I argue in Appendix 2, .

Назад: Appendix 1: Common Idioms
Дальше: Nil Guards