Ruby提供了两种以编程方式引发异常的可能性: raise并且fail都是Kernel方法.根据这些文件,它们完全相同.
出于习惯,我raise到目前为止只使用过.现在我找到了几个建议(例如这里),raise用于捕获异常,以及fail用于不应处理的严重错误.
但它真的有意义吗?当你编写一个类或模块,并在内心深处产生问题时fail,你正在查看代码的编程同事可能会很高兴地了解你的意图,但使用我的代码的人很可能不会看到我的代码,无法知道,异常是由a raise还是by 引起的fail.因此,我谨慎使用raise或fail不会对他的决定产生任何影响,无论她是否应该处理.
有人会在我的论点中看到瑕疵吗?还是有其他标准,我可能想用fail而不是raise?
简单的例子,它不适用于我的平台(Ruby 2.2,Cygwin):
#!/usr/bin/ruby
backtt = fork { exec('mintty','/usr/bin/zsh','-i') }
Process.detach(backtt)
exit
Run Code Online (Sandbox Code Playgroud)
这个小程序(从shell启动时)应该跨越一个终端窗口(mintty),然后让我回到shell提示符.
然而,虽然它创建了薄荷窗口,但之后我没有shell提示符,并且我无法在调用shell中键入任何内容.
但是当我在分离之前引入一个小延迟时,要么使用'sleep',要么在stdout上打印一些内容,它会按预期工作:
#!/usr/bin/ruby
backtt = fork { exec('mintty','/usr/bin/zsh','-i') }
sleep 1
Process.detach(backtt)
exit
Run Code Online (Sandbox Code Playgroud)
为什么这有必要?
顺便说一下,我很清楚我可以(从外壳)做一个
mintty /usr/bin/zsh -i &
Run Code Online (Sandbox Code Playgroud)
直接,或者我可以...... &从Ruby内部使用system(),但这不是重点.我特别感兴趣的fork/exec/detach是Ruby 中的行为.任何见解?
jruby 1.7.23(1.9.3p551)2015-11-24 f496dd5关于Java HotSpot(TM)64位服务器VM 1.7.0_79-b15 + jit [Windows 7-amd64]
我在我的脚本容器中运行一个scriptlet,如下所示:
(RubyObject) ro = (RubyObject)container.runScriptlet(org.jruby.embed.PathType.RELATIVE,"example.rb");
Run Code Online (Sandbox Code Playgroud)
其中container是ScriptingContainer类型."局部变量行为"设置为"瞬态".
文件example.rb包含以下行:
foo='xxx'
$bar='yyy'
'zzz'
Run Code Online (Sandbox Code Playgroud)
我可以从Java端检索值'zzz',因为它是从runScriptlet显式返回的.我还可以使用检索$ bar的值
container.get("$bar")
Run Code Online (Sandbox Code Playgroud)
有没有办法检索foo的值?container.get("foo")返回空指针.
我还尝试将局部变量行为更改为"持久",但结果仍然相同.
我已经通过此处找到的说明(即使用stack命令)在 MacOS Mojave 上安装了 Haskell 。然而,
import System.Random
Run Code Online (Sandbox Code Playgroud)
带来ghci了错误消息找不到模块 'System.Random'。通过寻找解决方案,我在 Stackoverflow 上遇到了这个讨论,我按照 Michael Snoyman 在那里发布的建议来尝试命令
stack install random
Run Code Online (Sandbox Code Playgroud)
在再次进入ghci之前。该命令产生了大量输出,其中一部分与 System.Random 相关:
随机>配置
random> 警告:random.cabal:15:2:在 15:2、16:2、17:2 处用作缩进的制表符
random> 配置 random-1.1...
随机>构建
random> random-1.1 的预处理库..
random> 为 random-1.1 构建库..
random> [1 of 1] 编译 System.Random
随机>
随机> /private/var/folders/bg/zjbyc9fj64d5kr98_x5bfjtm0000gn/T/stack946/random-1.1/System/Random.hs:43:1:警告:[-Wtabs]
random> Tab 字符在这里找到,还有 74 个位置。
随机> 请改用空格。
随机> |
随机> 43 | (
随机> | ^^^^^^^^^
现在我有一些问题:
(1) 我用这个stack install命令到底做了什么?我知道在不知道它应该做什么的情况下运行命令是有风险的,但事实是这正是我所做的。我的猜测是,这是获取一些库(类似于 …
在我的zsh脚本中,我有一条线
echo some text ================================
Run Code Online (Sandbox Code Playgroud)
令我惊讶的是,为此行发出了错误消息:
zsh: =============================== not found
Run Code Online (Sandbox Code Playgroud)
从命令行进行试验,我发现当有一个等号时,shell会感到沮丧:
$ echo =z
zsh: z not found
Run Code Online (Sandbox Code Playgroud)
但在这里,我们有:
$ echo =echo
/usr/bin/echo
Run Code Online (Sandbox Code Playgroud)
从这个观察来看,它看起来好像
=XXX
Run Code Online (Sandbox Code Playgroud)
会被解释为
$(which XXX)
Run Code Online (Sandbox Code Playgroud)
但是,我没有在zsh联机帮助页中找到任何有关此"替换"的内容.这块魔法描述在哪里?
我的问题是由触发这在SO讨论,这并没有导致一个答案,将真正说明问题。我在这里以稍微不同的方式“重写”它,因为我想更清楚真正的问题是什么,因此希望在这里得到答案。
考虑以下两个 Ruby 表达式:
1 * a - 31 && a = 3从 Ruby 优先级表中,我们知道这里提到的运算符*的优先级最高,其次是-,然后是&&,最后是=。
表达式没有括号,但是——正如我们可以在irb 中验证的那样,a在第一种情况下提供一个合适的值——它们被评估,就像括号分别写为(1*a) - 3, 一样1 && (a=3)。
第一个很容易理解,因为*绑定比-.
第二个不能这样解释。&&绑定强于=,因此如果仅优先级很重要,则解释应为(1 && a) = 3。
结合性(=右结合和-左结合)也不能解释这种效果,因为只有当我们有几个相同类型的运算符(例如x-y-z或x=y=z)时。
赋值运算符中必须有一些特殊规则,我在我检查过的文档中没有找到,特别是赋值和语法的文档。
有人可以指出,赋值运算符的这种特殊行为记录在哪里吗?或者我在这里错过/误解了什么?
我从包含字段的标准输入行中读取。字段分隔符是分号。输入中没有特定的引号字符(即字段本身不能包含分号或换行符)。输入字段的数量未知,但至少有 4 个。
输出应该是一个类似的文件,由从 2 到末尾的字段组成,但字段 2 和 3 的顺序相反。
我正在使用 zsh。
我想出了一个解决方案,但发现它很笨拙。特别是,我想不出任何特定于 zsh 的东西可以帮助我,所以基本上我恢复到awk. 这是我的方法:
awk -F ';' '{printf("%s", $3 ";" $2); for(i=4;i<=NF;i++) printf(";%s", $i); print "" }' <input_file >output_file
Run Code Online (Sandbox Code Playgroud)
第一个printf处理两个反转字段,然后我使用显式循环写出其余字段。awk(或 gawk)是否有可能在单个命令中打印一系列字段?或者我是否错过了 zsh 中一些非常聪明的功能,它可以让我的生活变得更简单?
更新:输入数据示例
a;bb;c;D;e;fff
gg;h;ii;jj;kk;l;m;n
Run Code Online (Sandbox Code Playgroud)
应该产生输出
c;bb;D;e;fff
ii;h;jj;kk;l;m;n
Run Code Online (Sandbox Code Playgroud) (我已经在Ruby论坛上问了这个问题,但它没有得出任何答案,所以我现在正在交叉)
根据我的理解,以下几段代码在Ruby 1.9及更高版本中是等效的:
# (1)
case
when x < y
foo
when a > b
bar
else
baz
end
# (2)
if x < y
foo
elsif a > b
bar
else
baz
end
Run Code Online (Sandbox Code Playgroud)
到目前为止,我总是习惯于使用(2).有人会想到一个特殊的原因,为什么(1)或(2)是"更好",还是仅仅是品味问题?
澄清:一些用户反对,这个问题只是"基于意见",因此不适合这个论坛.因此,我认为我没有说清楚自己:我不想开始讨论个人编程风格.我提出这个话题的原因是:
令我感到惊讶的是,Ruby提供了两种非常不同的语法(无目标情况,if-elsif),因为在我看来,它的目的完全相同,特别是因为if-elsif语法实际上是每个程序员都是熟悉.我甚至不会将'target-less if'视为"语法糖",因为它不允许我比'if-elsif'更明确地表达编程逻辑.
所以我想知道在什么情况下我可能想要使用'无目标案例'构造.它是否具有性能优势?它是否与if-elsif的某种微妙方式不同,我才注意到它?
关于实施无目标案件的其他调查结果:
Olivier Poulin已经指出,一个无目标的case语句会明确地使用===运算符来反对值"true",这会导致'case'与(if)相比(微小的)性能惩罚(和更多的原因,我不明白为什么有人可能想要使用它).
但是,在检查Ruby 1.9和Ruby 2.0的case语句的文档时,我发现它们对它的描述不同,但至少都表明在这种情况下可能不会使用===.在Ruby 1.9的情况下:
case语句由一个可选条件组成,该条件位于case的参数位置,而when子句则为零或更多.匹配条件的第一个when子句(或者如果条件为null则评估为布尔真值)"wins"
在这里它说,如果条件(即'case'之后的内容)为null(即不存在),则第一个'when'子句的求值为true的是正在执行的子句.这里没有提到===.
在Ruby 2.0中,措辞完全不同:
case表达式可以以两种方式使用.最常见的方法是将对象与多个模式进行比较.使用+ === +方法[.....]匹配模式.使用case表达式的另一种方法就像if-elsif表达式:[此处给出了无目标情况的例子].
因此,它表示===以"第一"方式使用(具有目标的情况),而无目标情况"就像"if-elsif.这里没有提到===.
我正在从Cygwin运行zsh.我的一个shell函数包含一个语句
rm -f somedir/*
Run Code Online (Sandbox Code Playgroud)
(我想删除somedir中的所有非隐藏文件,但不删除目录本身).但是,我总是被问到:
zsh: sure you want to delete all the files in ... [yn]?
Run Code Online (Sandbox Code Playgroud)
这条消息的措辞(注意开头的"zsh:")表明问题来自zsh,而不是rm.但是,rm是一个外部命令:
$ type rm
rm is /usr/bin/rm
Run Code Online (Sandbox Code Playgroud)
顺便说一下,如果我明确地调用rm as,也会出现提示
$ command rm -f somedir/*
Run Code Online (Sandbox Code Playgroud)
zsh中有什么东西,它试图太聪明吗?
(Crossposting note:这个问题也已于12月20日在JRuby邮件列表(jruby@ruby-lang.org)和1月2日的JRuby论坛上发布,但尚未得到任何回复.
这个问题是关于在存在多线程的情况下理解LocalContextScope参数的影响.
我们可以在JRuby Wiki上找到 一个有助于为LocalContextScope参数选择最佳值的配方.该页面解释了,此参数控制是否在线程之间共享ScriptingContainer和/或Ruby Runtime和/或Variable Map.但是,我希望对这个问题有一个更深入的了解,特别是"系统"的哪一部分实现在这三个组件中的哪一个中.
作为一个具体的例子:当我在Ruby中创建全局变量,或者在顶级上下文中创建新类或函数和变量时,它们是属于ScriptingContainer,运行时还是变量映射?除非知道这一点,否则我不知道我必须使用哪个LocalContextScope.