【发布时间】:2015-07-20 03:20:53
【问题描述】:
try method 是核心 Ruby 的常见扩展。例如,它在 Rails 中默认可用。 try 仅在对象不是 nil(Ruby 的 null)时才在对象上执行方法或代码块。它的用法分为三种:
在非
nil对象上调用方法并返回结果:customer_or_nil.try(:save)。如果目前的结果不是
nil:obj.try { |non_nil_obj| do_something(non_nil_obj) },则在表达式中链接任意代码块。(2) 的扩展不用于可选处理,而是作为继续链式表达式的一种方式,其中步骤 n+1 中的方法需要一个必须根据步骤 n 的结果计算的参数:
data.analyze.try { |result| result.compress(optimal_settings(result)) }.save
我对 (3) 的 Scala 等价物或替代 Scala 习惯用法特别感兴趣,例如,此代码与 Apache Spark 的DataFrame 相关:
val df = ctx.sql("select * from my_table")
df.
repartition(max(1, df.rdd.partitions.size / 4)).
saveAsTable("repartitioned_table")
重构为类似以下的内容(使用 Ruby 语法)
ctx.
sql("select * from my_table").
try { |df| df.repartition(max(1, df.rdd.partitions.size / 4)) }.
saveAsTable("repartitioned_table")
重构的目标是通过维护单个方法链来提高可读性,并通过将df 严格限制在链中绝对需要它的步骤来减少范围污染。
注意:我对使用Option 进行可选处理的利弊讨论特别不感兴趣,因为这不是try 这个问题所关注的主要用例。
【问题讨论】:
-
理解应该可以完成这项工作。 Scala 中的
Try是一个monad,这意味着flatmap()是在其上定义的。flatmap()在Try上的工作方式是将其参数应用于成功路径。for{ df <- ctx.sql(...); rep <- repartiion( ... ); sat <- saveAsTable(...); } -
@BobDalgleish 您错过了问题的目的:我正在寻找支持方法链接的答案。看看 Alexey 的回答。
标签: ruby-on-rails ruby scala apache-spark chaining