在模块中打开类

发布于 2024-11-01 09:51:18 字数 560 浏览 6 评论 0原文

我知道我可以执行以下命令向 String 类添加方法

class String
  def do_something
    puts self.size
  end
end

var = "test"
var.do_something

,这将返回 4

我希望能够拥有一个带有接受 String 的函数的模块,但能够调用该字符串上的 do_something 方法(例如见下文)-可能吗?

编辑:添加了不起作用的示例代码

module TestModule
  class String
    def do_something
      puts self.size
    end
  end

  def self.test(str)    
    str.do_something
  end
end

这给出了错误:undefined method 'do_something' for "hello":String (NoMethodError)

I know I can execute the following to add methods to the String class

class String
  def do_something
    puts self.size
  end
end

var = "test"
var.do_something

and this will return 4

I want to be able to have a module with a function that takes in a String, but be able to call the do_something method on this string (see below for example) - is it possible?

EDIT: Added sample code that is not working

module TestModule
  class String
    def do_something
      puts self.size
    end
  end

  def self.test(str)    
    str.do_something
  end
end

This gives the error: undefined method 'do_something' for "hello":String (NoMethodError)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

双马尾 2024-11-08 09:51:18

按照编写代码的方式,您定义了一个名为 TestModule::String 的新类。如果要修改内置 Ruby String 类,并且要将声明保留在模块内,则需要使用 String 的完全限定名称(带有“::”)。

module TestModule
  class ::String
    def do_something
      puts self.size
    end
  end

  def self.test(str)  
    str.do_something
  end
end

添加“::”告诉 Ruby 您想要的 String 类不是 TestModule 的一部分。

在同一文件中的 TestModule 之外声明 String 可能会更干净。

如果您不想污染全局 String 类,那么 您想要添加方法的字符串实例。

module TestModule
  def self.test(str)  
    do_somethingify!(str)
    str.do_something
  end

  def self.do_somethingify!(str)
    unless str.respond_to? :do_something
      str.instance_eval do
        def do_something
          puts size
        end
      end
    end
  end      
end          

The way your code is written, you're defining a new class called TestModule::String. If you want to modify the built-in Ruby String class, you need to use the fully-qualified name of String (with the ""::") if you want to keep the declaration inside the module.

module TestModule
  class ::String
    def do_something
      puts self.size
    end
  end

  def self.test(str)  
    str.do_something
  end
end

Adding the "::" tells Ruby that the String class that you want is not part of the TestModule.

It's probably cleaner to just declare String outside of TestModule in the same file.

If you don't want to pollute the global String class, you could just modify the specific String instance that you want to add the method to.

module TestModule
  def self.test(str)  
    do_somethingify!(str)
    str.do_something
  end

  def self.do_somethingify!(str)
    unless str.respond_to? :do_something
      str.instance_eval do
        def do_something
          puts size
        end
      end
    end
  end      
end          
甜尕妞 2024-11-08 09:51:18

也许是这个?

module TestModule
  module_function
  def test(str)
    str.instance_eval{doSomething}
  end
end

Test.test(str)

编辑由于问题的更改而更改

只需将doSomething的定义放在TestModule类之外。

class String
  def doSomething
    puts size
  end
end

module TestModule
  module_function
  def test(str)  
    str.doSomething
  end
end

Maybe this?

module TestModule
  module_function
  def test(str)
    str.instance_eval{doSomething}
  end
end

Test.test(str)

Edit Changed due to the change in the question

Just put the definition of doSomething outside out the TestModule class.

class String
  def doSomething
    puts size
  end
end

module TestModule
  module_function
  def test(str)  
    str.doSomething
  end
end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文