2015-07-20 43 views
1

try method是核心Ruby的常见扩展。例如,它在Rails中默认可用。 try只有当它不是nil(Ruby的null)时,才会在对象上执行一个方法或一段代码。它的用法有三种形式:Scala等效于Ruby中的ActiveSupport的Object.try

  1. 调用非nil对象的方法,并返回结果:
    customer_or_nil.try(:save)

  2. 链接的代码的任意块中的表达式如果结果到目前为止不nil
    obj.try { |non_nil_obj| do_something(non_nil_obj) }

  3. (2)使用不用于可选的处理,但作为一种方法来继续链状表达式,其中在步骤n + 1个的方法要求必须根据步骤n的结果而计算出的参数的扩展:
    data.analyze.try { |result| result.compress(optimal_settings(result)) }.save

我在Scala的当量(3)或可替换的Scala成语的,将允许特别感兴趣,例如,与此相关的代码的Apache火花的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这个问题涉及的主要用例。

+0

一种-理解应该做的工作。 Scala中的'Try'是一个monad,意味着'flatmap()'被定义在它上面。 ''flatmap()'在'Try'上工作的方式是将其参数应用于成功的路径。 '为{df < - ctx.sql(...); rep < - repartiion(...); sat < - saveAsTable(...); }' –

+0

@BobDalgleish你错过了这个问题的目的:我正在寻找一个支持方法链接的答案。看看Alexey的回答。 – Sim

回答

1

不是在标准库,而是一个相当于3个很容易写(try是一个关键字,所以改名为ap(简称apply)):

implicit class TryOp[A](x: A) { 
    def ap[B](f: A => B): B = f(x) 
} 

ctx. 
    sql("select * from my_table"). 
    ap { df => df.repartition(max(1, df.rdd.partitions.size/4)) }. 
    saveAsTable("repartitioned_table") 
+1

不适用于我:'null.ap(identity _)// :12:error:value ap is not the member of Null' –

+0

@JörgWMittag我可以重现上面的错误,但是当我使用'ap '什么应该是来自Spark SQL的null值(使用'Any'值变量)我没有错误。 – Sim

+0

Alexey,以任何方式解决@JörgWMittag发现的问题? – Sim