是否有 Ruby 模块或类提供有关当前正在运行但不是当前进程的信息?例如,如果我有 pid 1234,我想获取有关进程用户、时间等的信息。我可以通过 shell 来获取此信息ps
,但我更喜欢从 Ruby 获取信息。例如,类似于以下虚构代码:
require 'process/info'
process = ProcessInfo.new(1234)
puts process.pid
puts process.user
任何帮助都值得感激。
是否有 Ruby 模块或类提供有关当前正在运行但不是当前进程的信息?例如,如果我有 pid 1234,我想获取有关进程用户、时间等的信息。我可以通过 shell 来获取此信息ps
,但我更喜欢从 Ruby 获取信息。例如,类似于以下虚构代码:
require 'process/info'
process = ProcessInfo.new(1234)
puts process.pid
puts process.user
任何帮助都值得感激。
尽管bsearch
和bsearch_index
对于整数数组来说工作正常,但它们似乎对字符串数组存在问题。
sorted_strings = %w[aaa aab aac bbb bbc bbd ccc ccd cce]
#=> ["aaa", "aab", "aac", "bbb", "bbc", "bbd", "ccc", "ccd", "cce"]
sorted_strings.bsearch_index { |x| x.start_with? 'a' }
#=> nil
sorted_strings.bsearch_index { |x| x.start_with? 'aaa' }
#=> nil
sorted_strings.bsearch_index { |x| x.start_with? 'b' }
#=> 3
sorted_strings.bsearch_index { |x| x.start_with? 'c' }
#=> 6
sorted_strings.bsearch_index { |x| x.start_with? 'cce' }
#=> 8
sorted_strings.bsearch { |x| x.start_with? 'a' }
#=> nil
sorted_strings.bsearch { |x| x.start_with? 'aa' }
#=> nil
sorted_strings.bsearch { |x| x.start_with? 'aaa' }
#=> nil
sorted_strings.bsearch { |x| x.start_with? 'b' }
#=> "bbb"
永远不应该返回 Nil。这是一个错误吗?
与组合比较运算符进行比较时,会返回更疯狂的结果:
sorted_strings = %w[aaa aab aac bbb bbc bbd ccc ccd cce]
#=> ["aaa", "aab", "aac", "bbb", "bbc", "bbd", "ccc", "ccd", "cce"]
sorted_strings.bsearch_index { |x| x <=> 'a' }
#=> nil
sorted_strings.bsearch_index { |x| x <=> 'aaa' }
#=> nil
sorted_strings.bsearch_index { |x| x <=> 'b' }
#=> nil
sorted_strings.bsearch_index { |x| x <=> 'bbb' }
#=> nil
sorted_strings.bsearch_index { |x| x <=> 'bbc' }
#=> 4
鉴于上述方法无效,我不明白为什么下面的方法有效:
sorted_strings = %w[aaa aab aac bbb bbc bbd ccc ccd cce]
#=> ["aaa", "aab", "aac", "bbb", "bbc", "bbd", "ccc", "ccd", "cce"]
sorted_strings.bsearch_index { |x| x >= 'a' }
#=> 0
sorted_strings.bsearch_index { |x| x >= 'aa' }
#=> 0
sorted_strings.bsearch_index { |x| x >= 'aaa' }
#=> 0
sorted_strings.bsearch_index { |x| x >= 'b' }
#=> 3
sorted_strings.bsearch_index { |x| x >= 'bbc' }
#=> 4
sorted_strings.bsearch_index { |x| x >= 'cc' }
#=> 6
sorted_strings.bsearch_index { |x| x >= 'cce' }
#=> 8
这是我使用的 Ruby 版本:
$ ruby -v
ruby 3.2.2 (2023-03-30 revision e51014f9c0) [x86_64-linux]
我正在学习 Ruby 并查看了Array#map
这里的文档,它说语法如下
map {|element| ... } → new_array
map → new_enumerator
但是我们可以arr.map(&:to_s)
对数组的每个元素进行字符串化。据我所知,&:to_s
这只是语法糖:to_s.to_proc
(如此处所示),这意味着 map 接受一个Proc
对象作为参数。但它的函数签名却并非如此。
我对此有几个疑问。
有人可以解释这种行为并指出相关文档吗?
在这种情况下到底是什么Proc
意思? 这不是to_s
底层类的方法吗? 对于我来说,传递一个没有关于将要调用的底层类Proc
的信息的对象意味着什么。to_s
任何帮助都将非常有帮助!
使用 rspec-expectations 3.13.3 并具有如下代码:
def methname(**kwargs)
# let's assume this method doesn't mind whether the kwargs are keyed by symbols or strings
p(received: kwargs)
end
使用如下测试
expect(something).to receive(:methname).with(hash_including(what_ever: "else"))
但在某些情况下,关键字参数被创建为字符串,而不是符号,因此失败了,我必须这样做
expect(something).to receive(:methname).with(hash_including("what_ever" => "else"))
我可以在每个规范中做到这一点,但如果我可以无差别地匹配它,对我来说会更干净 -
# desired code
expect(something).to receive(:methname).with(hash_including_indifferently(what_ever: "else"))
有没有办法可以做到这一点?
在 vanilla ruby 中,如果我在默认主范围内创建方法:
def asdf
puts "asdf"
end
def qwer
puts "qwer"
end
我该如何列出这些功能?
我尝试了以下方法,但没有成功:
methods.grep(/asdf|qwer/)
self.methods.grep(/asdf|qwer/)
Object.methods.grep(/asdf|qwer/)
Object.instance_methods.grep(/asdf|qwer/)
我在 Windows 10 上运行 ruby,通过https://scoop.sh/安装:
> ruby --version
ruby 3.3.1 (2024-04-23 revision c56cd86388) [x64-mingw-ucrt]
我用 Ruby 编写了一个凯撒密码加密程序。当我传入包含小写字符的字符串时,它似乎工作正常,直到我传入包含大写字符的字符串。每当我传入包含大写字符的字符串时,代码就会在行间引发 NoMethodError main.rb:7:in block in `caeser_cipher': undefined method `+' for nil (NoMethodError)
。
这是我的代码:
def caeser_cipher(string, key)
alphabet = ('a'..'z').to_a
cipher = ""
string.each_char do |char|
if alphabet.include?(char.downcase)
new_key = (alphabet.index(char) + key) % 26
char = alphabet[new_key]
end
cipher << char
end
cipher
end
puts "Enter whatever you please (of course a string of text) that you want encrypted!!!"
text = gets.chomp
puts "And then the offset value"
num = gets.chomp.to_i
puts caeser_cipher(text, num)
我尝试包装char = alphabet[new_key]
另一个 if 条件来检查char == char.upcase
,如果结果为真,则执行此操作,char = alphabet[new_key].upcase
但也失败了。
我是 Jekyll 主题 ( Beautiful Jekyll )的作者,它可以作为 Ruby gem 或 GitHub Pages 主题安装
我最近发现 Jekyll 可以在 Windows 上运行。从文档中可以看出, Windows上的 Gemfile 中需要包含 gems tzinfo
。tzinfo-data
我的问题是:既然我的主题不仅供我使用,那么这些 gem 是否应该添加到 gemspec 而不是 Gemfile 中?我想确保在 Windows 上安装我的主题的任何人都可以使用它。
我刚刚了解到 Ruby 有一种称为 的特殊方法undef_method
。它实际上取消了现有方法的定义。
您undef_method
可以<
像下面这样从 Integer 中取消定义:
class Integer
undef_method :<
end
begin
puts 1 < 2
rescue Exception => exception
puts exception
puts 1.0 < 2
end
结果如下:
undefined method `<' for an instance of Integer
true
这是可以理解的,因为 Ruby 本身是高度面向对象的,并且一切都是对象,包括其类型系统等。
但是您可以取消定义,undef_method
以使从整数取消定义变得不可能<
。
class Module
undef_method :undef_method
end
class Integer
undef_method :<
end
begin
puts 1 < 2
rescue Exception => exception
puts exception
puts 1.0 < 2
end
既然它undef_method
本身未定义,你就无法真正<
从 Integer 中取消定义。
temp.rb:6:in `<class:Integer>': undefined method `undef_method' for class Integer (NoMethodError)
undef_method :<
^^^^^^^^^^^^
from temp.rb:5:in `<main>'
因此问题是:undef_method
当 ruby 变得未定义时,它如何执行?
如果 Ruby 是编译型语言,我假设 Ruby 会先加载方法,然后执行自定义代码,这样就没问题了!但是 Ruby 是解释型语言,在执行代码之前不会加载代码。
我认为这可能会导致问题,因为如果方法在执行时未定义,Ruby 就无法判断要执行什么代码。
我正在尝试构建 Ruby 宝石。我使用基于 Ruby 3.3 和 devcontainer 的 Docker 映像设置了开发环境。
我使用工具初始化了一个 gem bundle gem
。这设置了创建新 gem 所需的基本结构。这安装了 MiniTest 5.25.1 和 Rubocop 1.67.0,以及一些其他依赖项。
我做的第一件事是将 SimpleCov 添加到我的 Gemfile 中,然后bundle install
安装 SimpleCov 0.22.0。我通过更新来配置 SimpleCov,test/test_helper.rb
以要求 SimpleCov 和SimpleCov.start
。
然后,我将第一个文件添加到我的 Gem 中lib/gemname/modulename/file.rb
,并添加了相应的测试test/gemname/modulename/test_file.rb
。编写了一个非常简单的几行方法和一个测试来调用该方法并对其进行断言。我想验证 MiniTest、SimpleCov 和 Rubocop 是否正常运行。
当我运行bundle exec rake
测试和 Rubocop 时,输出似乎表明覆盖率报告是在执行测试之前生成的:
Coverage report generated for Minitest to /workspaces/gemname/coverage.
Line Coverage: 75.0% (9 / 12)
Run options: --seed 44598
# Running:
..
Finished in 0.001718s, 1164.1532 runs/s, 1164.1532 assertions/s.
2 runs, 2 assertions, 0 failures, 0 errors, 0 skips
SimpleCov 自述文件中的一项建议是尝试.simplecov
在项目根目录中使用一个文件。当我按照这些说明操作时,输出略有变化,但仍然表明 SimpleCov 覆盖率报告在测试套件之前被调用,甚至在测试助手中的 require 之前被调用:
Warning: Error occurred while trying to load /workspaces/gemname/.simplecov. Error message: uninitialized constant Simplecov
Run options: --seed 20890
# Running:
..
Finished in 0.001560s, 1281.7818 runs/s, 1281.7818 assertions/s.
2 runs, 2 assertions, 0 failures, 0 errors, 0 skips
我确实注意到生成的 gemspec 文件包含版本文件的 require 语句以及spec.require_paths
。我删除了这两个文件以查看是否会产生影响,但结果没有。即使没有这些,SimpleCov 似乎也会在测试运行之前尝试生成其覆盖率报告。
由于 gemspec 加载较早,我预计lib/gemname/version.rb
文件覆盖范围会出现问题,因为它在 SimpleCov 之前加载。但是,我已确认 SimpleCov 是必需的,并且在首次加载测试类后启动。
由于用 实例化的 gembundle gem
包含跨多个文件的整个目录结构和配置,所以很难获取具体的代码,但我整理了一个演示此行为的最基本的存储库,并将其放在 GitHub 上提供。
我如何确保 SimpleCov 等到测试完成后再生成覆盖率报告?
我的假设是否正确,Ruby在字符串插值期间解释对象时不会调用to_s
或方法?to_str
String
a = "Hallo"
class String
def to_s
"Servus"
end
end
def a.to_s
"Servus"
end
puts "Hier sagt man #{a}"
=> 在这里说 你好
检查一个对象是否String
比简单地调用该to_s
方法更有效率?