Why are exclamation marks used in Ruby methods?

后端 未结 10 2066
小蘑菇
小蘑菇 2020-11-22 06:01

In Ruby some methods have a question mark (?) that ask a question like include? that ask if the object in question is included, this then returns a

相关标签:
10条回答
  • 2020-11-22 06:04
    !
    

    I like to think of this as an explosive change that destroys all that has gone before it. Bang or exclamation mark means that you are making a permanent saved change in your code.

    If you use for example Ruby's method for global substitutiongsub!the substitution you make is permanent.

    Another way you can imagine it, is opening a text file and doing find and replace, followed by saving. ! does the same in your code.

    Another useful reminder if you come from the bash world is sed -i has this similar effect of making permanent saved change.

    0 讨论(0)
  • 2020-11-22 06:09

    From themomorohoax.com:

    A bang can used in the below ways, in order of my personal preference.

    1) An active record method raises an error if the method does not do what it says it will.

    2) An active record method saves the record or a method saves an object (e.g. strip!)

    3) A method does something “extra”, like posts to someplace, or does some action.

    The point is: only use a bang when you’ve really thought about whether it’s necessary, to save other developers the annoyance of having to check why you are using a bang.

    The bang provides two cues to other developers.

    1) that it’s not necessary to save the object after calling the method.

    2) when you call the method, the db is going to be changed.

    http://www.themomorohoax.com/2009/02/11/when-to-use-a-bang-exclamation-point-after-rails-methods

    0 讨论(0)
  • 2020-11-22 06:11

    ! typically means that the method acts upon the object instead of returning a result. From the book Programming Ruby:

    Methods that are "dangerous," or modify the receiver, might be named with a trailing "!".

    0 讨论(0)
  • 2020-11-22 06:14

    In general, methods that end in ! indicate that the method will modify the object it's called on. Ruby calls these as "dangerous methods" because they change state that someone else might have a reference to. Here's a simple example for strings:

    foo = "A STRING"  # a string called foo
    foo.downcase!     # modifies foo itself
    puts foo          # prints modified foo
    

    This will output:

    a string
    

    In the standard libraries, there are a lot of places you'll see pairs of similarly named methods, one with the ! and one without. The ones without are called "safe methods", and they return a copy of the original with changes applied to the copy, with the callee unchanged. Here's the same example without the !:

    foo = "A STRING"    # a string called foo
    bar = foo.downcase  # doesn't modify foo; returns a modified string
    puts foo            # prints unchanged foo
    puts bar            # prints newly created bar
    

    This outputs:

    A STRING
    a string
    

    Keep in mind this is just a convention, but a lot of Ruby classes follow it. It also helps you keep track of what's getting modified in your code.

    0 讨论(0)
  • 2020-11-22 06:19

    It is most accurate to say that methods with a Bang! are the more dangerous or surprising version. There are many methods that mutate without a Bang such as .destroy and in general methods only have bangs where a safer alternative exists in the core lib.

    For instance, on Array we have .compact and .compact!, both methods mutate the array, but .compact! returns nil instead of self if there are no nil's in the array, which is more surprising than just returning self.

    The only non-mutating method I've found with a bang is Kernel's .exit! which is more surprising than .exit because you cannot catch SystemExit while the process is closing.

    Rails and ActiveRecord continues this trend in that it uses bang for more 'surprising' effects like .create! which raises errors on failure.

    0 讨论(0)
  • 2020-11-22 06:20

    Simple explanation:

    foo = "BEST DAY EVER" #assign a string to variable foo.
    
    => foo.downcase #call method downcase, this is without any exclamation.
    
    "best day ever"  #returns the result in downcase, but no change in value of foo.
    
    => foo #call the variable foo now.
    
    "BEST DAY EVER" #variable is unchanged.
    
    => foo.downcase! #call destructive version.
    
    => foo #call the variable foo now.
    
    "best day ever" #variable has been mutated in place.
    

    But if you ever called a method downcase! in the explanation above, foo would change to downcase permanently. downcase! would not return a new string object but replace the string in place, totally changing the foo to downcase. I suggest you don't use downcase! unless it is totally necessary.

    0 讨论(0)
提交回复
热议问题