你如何定义&拨打" variable.my_function"在类中的Ruby中的方法?

时间:2016-09-12 13:10:05

标签: ruby class methods

所以基本设置如下:

app / services / SomeService / ABC.rb

class SomeService::ABC 
 FORBIDDEN_CHARS = {" " => "+", "'" => "%27", "/" => "%2F", ":" => "%3A", "&" => "%26"}
 def my_function(input)
  #now do something fancy with the input
  var = .... #a String is created
  var.to_linkable
 # continue with something fancy
 end

 def to_linkable
  FORBIDDEN_CHARS.each{|key,value| self.gsub!(key,value)}
 end
end

这会导致错误:未定义的方法`to_linkable' for" bla bla":String

但是这样可行:

def to_linkable(link)
    FORBIDDEN_CHARS.each{|key,value| link.gsub!(key,value)}
end

但我必须使用&to -linkable(链接)'来调用它。而不仅仅是把#link; to_linkable'。如果我以第一种方式复制粘贴在终端中的代码,那么在调用' link.to_linkable'时就没有错误。

所以我的问题是:我如何(以及在​​哪里?)正确创建这样一个to_linkable方法?我可能想稍后使用它,这就是为什么我希望它是一个易于使用的方法。非常感谢 :) 是的,我是一个Ruby新手,来自Matlab:D

4 个答案:

答案 0 :(得分:3)

首先,不要重新发明轮子。使用A failing assumption in a @Before or @BeforeClass method will have the same effect as a failing assumption in each @Test method of the class.,而不是尝试手动定义要替换的字符。

但是,为了学习,如果我们继续你的实施......

var是一个字符串。如果您希望在字符串上调用方法,则必须在String类中定义它。通常不建议将方法添加到这样的核心类,但以下方法可行:

class String
  FORBIDDEN_LINK_CHARS = {" " => "+", ...}
  def to_linkable
    FORBIDDEN_LINK_CHARS.each{|key,value| self.gsub!(key,value)}
    self
  end
end

"hello world".to_linkable # => "hello+world"

或者,如果您不想扩展String类,但仍希望在不传递变量的情况下调用实例方法,则需要将var设置为<类中的strong>实例变量。这可能是也可能不是一个好主意,取决于班级的结构。

例如,以下作品:

class SomeService::ABC 
  FORBIDDEN_CHARS = {" " => "+", ...}
  def my_function(input)
    @var = .... #a String is created
    make_var_linkable
  end

  def make_var_linkable
    FORBIDDEN_CHARS.each{|key,value| @var.gsub!(key,value)}
  end
end

...但是,回到我原来的观点,我推荐的实际实施不属于上述情况。只是做:

require 'uri'

class SomeService::ABC 
  def my_function(input)
    var = URI.escape(....)
  end
end

答案 1 :(得分:2)

目前为止给出的两个答案都使用了FORBIDDEN_LINK_CHARS.lengthgsub次操作,这不是最佳选择。

module StringWithForbiddenChars
  FORBIDDEN_LINK_CHARS = {" " => "+", ...}
  def to_linkable
    gsub Regexp.union(FORBIDDEN_LINK_CHARS.keys), FORBIDDEN_LINK_CHARS
  end
  def to_linkable!
    self.tap do |s|
      s.gsub! Regexp.union(FORBIDDEN_LINK_CHARS.keys), FORBIDDEN_LINK_CHARS
    end
  end
end
String.prepend StringWithForbiddenChars
# or to extend the specific instance of a string:
# (str = "hello world").extend(StringWithForbiddenChars)

"hello world".to_linkable
#⇒ "hello+world"

答案 2 :(得分:1)

当您在另一个类中编写class String; ...; end时,您正在创建新类,而不是编辑现有的ruby核心String类。基本上可以说像String::ABC != String。所以你应该首先定义你的新String方法:

class String
  FORBIDDEN_CHARS = {" " => "+", "'" => "%27", "/" => "%2F", ":" => "%3A", "&" => "%26"}

  def to_linkable
    FORBIDDEN_CHARS.each{ |key, value| self.gsub!(key,value) }
    self
  end      
end

之后,您可以在任何带有字符串对象的地方使用此方法。例如,在SomeService

class SomeService
  def my_function(input)
    #now do something fancy with the input
    var = "#{input}    " #a String is created
    var.to_linkable
    # continue with something fancy
  end
end

所以最后你可以这样做:

SomeService.new.my_function("': 123123&")
# =>"%27%3A+123123%26++++"

答案 3 :(得分:0)

如果你不想&#34;污染&#34;整个字符串 class ,您可以使用模块extend特定的字符串实例

module SomeService
  FORBIDDEN_CHARS = {" " => "+", "'" => "%27", "/" => "%2F", ":" => "%3A", "&" => "%26"}

  class ABC
    def my_function(input)
      # ...
      var = # a String is created
      var.extend(Linkable)
      var.to_linkable
      # ...
    end
  end

  module Linkable
    def to_linkable
      FORBIDDEN_CHARS.each { |key, value| gsub!(key,value) }
    end
  end
end