question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Request: Add Optional() function for Objects and Maps.

See original GitHub issue

Hi there.

I would like to request an Optional() function for map-like objects. If a key is not present in an object, normally a keyError returns. Optional(object.key) will return None when the key is not present. I could not find such a thing in the current WDL implementation (but I may have overlooked).

That would be useful in these types of situations:

task exampleTask {
  String requiredVariable
  String? optionalString = "sensible default here"
  Int? optionalInt = 3
  Boolean? optionalBool = false
  command {
  # insertcommandhere
  }
}
workflow exampleWf {
  Array[Object] objectList
  scatter(exampleObject in objectList) {
    call exampleTask {
      input: 
        requiredVariable=exampleObject.requiredVariable
        optionalString=Optional(exampleObject.optionalString)
        optionalInt=Optional(exampleObject.optionalInt)
        optionalBool=Optional(exampleObject.optionalBool)
     }
  }
}

Originally (without optional) your inputs.json would look like this:

{
  "exampleWf.objectList":
  [
    {
      "requiredVariable": "Sample1",
      "optionalString": "someOption",
      "optionalInt": 3,
      "optionalBool": false
    },
    {
      "requiredVariable": "Sample2",
      "optionalString":  "sensible default here",
      "optionalInt": 5,
      "optionalBool": false
    }
  ]
}

But with Optional() it can look like this:

{
  "exampleWf.objectList":
  [
    {
      "requiredVariable": "Sample1",
      "optionalString": "someOption"
    },
    {
      "requiredVariable": "Sample2",
      "optionalInt": 5
    }
  ]
}

When there are 10 optional values, this save a lot of typing and unnecessary duplication in the JSON. Why specify all these values if they have sensible defaults? There are quite some command line tools with many optional parameters that this feature seems very useful to me. Real word example:

task centrifugeDownload {
    String centrifugeOutput
    Array[String] domain
    String? seqTaxMap
    String? database = "refseq"
    String? centrifugeDownloadExecutable = "centrifuge-download"
    String? assemblyLevel = "Complete Genome"
    String? refseqCategory =  "any"
    Array[String]? taxIds = ["any"]
    Boolean? filterUnplaced = false
    Boolean? maskLowComplexRegions = false
    Boolean? downloadRnaSeqs = false
    Boolean? modifyHeader = false
    Boolean? downloadGiMap = false

    command {
        ${centrifugeDownloadExecutable} \
        -o ${centrifugeOutput} \
        -d ${sep=',' domain} \
        -a "${assemblyLevel}" \
        -c ${refseqCategory} \
        -t ${sep=',' taxIds} \
        ${true='-r' false='' downloadRnaSeqs} \
        ${true='-u' false='' filterUnplaced} \
        ${true='-m' false='' maskLowComplexRegions} \
        ${true='-l' false='' modifyHeader} \
        ${true='-g' false='' downloadGiMap} \
        ${database} \
        ${">> " + seqTaxMap}
    }
 }

I happen to have some experience with programming in Scala, so if you give me some pointers, I could possibly implement this myself.

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:7 (7 by maintainers)

github_iconTop GitHub Comments

2reactions
patmageecommented, Jan 11, 2018

By convention map values are optional, as there are no restrictions on what the key value can be. The key error is really an access error which is what you would expect to receive in the event of a missing value.

What I think would make a better approach would be a single engine function or modifying an existing one, to test for a key in a map.

task {
  Map[String,Int] my_values
  Int code = if contains_key(my_values,"key") then my_values["key"] else 0
  Int? code_2 = if contains_key(my_values,"key_2") then my_values["key"] else null
}

@geoffjentry @cjllanwarne has there ever been any talk of including a check like this?

0reactions
freeseekcommented, Jul 28, 2020

The following works a bit better:

scatter (key in keys(map)) { Boolean? is_key = if key == "xxx" then true else None }
if (length(select_all(is_key))>0) { ... }
Read more comments on GitHub >

github_iconTop Results From Across the Web

Optional chaining (?.) - JavaScript - MDN Web Docs
The optional chaining ( ?. ) operator accesses an object's property or calls a function. If the object is undefined or null ,...
Read more >
How can I map some parameters to be optional?
So, closest workaround I can do involves that two-object-literal solution I mentioned: interface PropType<T> { type: T }.
Read more >
Guide To Java 8 Optional | Baeldung
A value is present only if we have created Optional with a non-null value. We'll look at the isPresent() method in the next...
Read more >
Optional (Java Platform SE 8 ) - Oracle Help Center
A container object which may or may not contain a non-null value. If a value is present, isPresent() will return true and get()...
Read more >
Java Optional Tutorial with Examples - CalliCoder
ifPresent() method allows you to pass a Consumer function that is executed if a value is present inside the Optional object. It does...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found