【问题标题】:ruby modify objectruby 修改对象
【发布时间】:2011-07-22 02:29:57
【问题描述】:

我有代码:

def crop_word (film_title)
  size = film_title.size
  film_title[0...size-2] if size > 4
end

film = "Electrocity"
p crop_word film

如果我想修改对象film,我该怎么做? (如何创建crop_word 方法作为mutator 方法?)

p crop_word film #=> "Electroci"
p crop_word film #=> "Electro"
p crop_word film #=> "Elect"

【问题讨论】:

  • 考虑调用你的方法crop_word!来表明它是可变的。

标签: ruby


【解决方案1】:
def crop_word! (film_title)
  film_title.size > 4 ? film_title.slice!(0..-3) : film_title
end

puts crop_word! "1234567" #=>"12345"

【讨论】:

  • 应该返回nilunless size > 4
【解决方案2】:

问题不清楚。我想如果最后一个字符长于 4,你想删除它。

class String
    def crop_word!; replace(self[0..(length > 4 ? -2 : -1)]) end
end


puts 'Electrocity'.crop_word! # => 'Electrocit'

【讨论】:

    【解决方案3】:

    在 Ruby 中,您不能像在类 C 语言中那样通过引用传递参数。最简单的方法是返回新值,然后赋值给输入变量。

    film_title = crop_word(film_title)
    

    你可以做的就是把film_title放在一个容器里。

    class Film
      attr_accessor :title, :length
    end
    
    film = Film.new
    film.title = "Butch Cassidy and the Sundance Kid"
    
    def crop_word (film)
      length = film.title.length
      film.title=film.title[0..length-2] if length > 4
    end
    
    puts crop_word(film)
    # Butch Cassidy and the Sundance K
    puts crop_word(film)
    # Butch Cassidy and the Sundance
    puts crop_word(film)
    # Butch Cassidy and the Sundan
    

    我不推荐它,但你也可以修改 String 类

    class String
      def crop_word!
        self.replace self[0..self.length-2] if self.length > 4
      end
    end
    
    title = "Fear and Loathing in Las Vegas"
    
    title.crop_word!
    # => "Fear and Loathing in Las Vega"
    title.crop_word!
    # => "Fear and Loathing in Las Veg"
    title.crop_word!
    # => "Fear and Loathing in Las Ve"
    

    最后是 eval 和 binding 的 black magic,你可能不得不疯狂地实际使用它。

    def crop_word(s, bdg)
      eval "#{s}.chop!.chop! if #{s}.length > 4", bdg
    end
    
    title="The Dark Knight"
    crop_word(:title, binding)
    puts title
    # The Dark Knig
    crop_word(:title, binding)
    puts title
    # The Dark Kn
    crop_word(:title, binding)
    puts title
    # The Dark
    

    此外,您的 crop_word 不会输出您想要的内容,因为它保留了尾随空格。

    【讨论】:

    • 对不起,那是错误的。这里不需要包装器,String#slice!方法会很好地完成这项工作。
    • 当然,这并不是要解决字符串切片问题,而是要更广泛地解释 Ruby 所具有的功能,而不是引用/输出变量。
    【解决方案4】:
    def crop_word (film_title)
      size = film_title.size
      film_title[size-2..size]="" if size > 4
      film_title
    end
    

    一般而言,您要么必须使用已经进行就地突变的方法,要么重新打开相关类并分配给self

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-26
      • 2012-10-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多