-2

In most programming languages that have control-flow keywords, each control-flow keyword has one clear and unambiguous meaning. And then there's Ruby, in which the meaning of return is contextual: it does two very different things depending on whether or not you're inside of some (but not all!) types of anonymous functions. I'm not familiar with any other language with similar semantics.

That being true, if I have some Ruby code that's reasonably well written, and I want to translate it into another language, (let's say C#, because it's pretty popular around here,) how would I handle the "special" returns in order to preserve the original behavior?

The closest thing I can think of is to turn a "special" return into a throw new RubyNestedReturnException(<return value here>) and put all invocations in a try/catch block that catches RubyNestedReturnException and returns the value inside. This would probably work, but it would be very messy. Is there any better way to do it? (And no, "just turn all invocations that use a proc with "special" returns into a return statement" is not a good answer, since some invocations involve a proc that gets passed in as an argument from outside the function that invokes them.)

Community
  • 1
  • 1
Mason Wheeler
  • 82,511
  • 50
  • 270
  • 477
  • 4
    Keep in mind that translating from one language to another is often *not* a direct line-by-line conversion. Structures which make sense in one language are not guaranteed or even required to make sense in the other. Writing Ruby-ish code in C# is going to be no better than writing C#-ish code in Ruby. Which may look sensible to a seasoned C# developer, and may look terribly silly to even a novice Ruby developer. – David Aug 11 '15 at 18:20
  • From what I can infer from the linked question, it looks like it's not the `return` per se. I don't know what's a `Proc`, but it looks more like a C# `{}` block than a lambda, except you can't reference blocks in C#. C# lambdas behave just like Ruby's lambdas wrt `return`. – Lucas Trzesniewski Aug 11 '15 at 18:23
  • @LucasTrzesniewski: It's essentially a mutant hybrid of a `{}` block and a lambda. :P – Mason Wheeler Aug 11 '15 at 18:25

1 Answers1

2

C# has no direct equivalent. The try..catch hack may work on the surface, but you'll be better served translating the code to the language of your choice.

I mean no self respecting programmer would ever write a plain for i=1 to 10 (or equivalent) in Python, no matter what other languages say. It's simply not the "Pythonic" way. C# has more traditional roots (C++), so writing C#-like code should be relatively straight forward.

If you are interested, both C (setjmp/longjmp) and Java (break label;) have something similar, and both are (generally) viewed as code smell generators. I suggest avoiding it altogether and rewriting the code using more traditional control flow operations.

Blindy
  • 65,249
  • 10
  • 91
  • 131
  • For the record I like the idea of `break label`, and I'd use it if it was in C#. But yeah, most people balk at it. – Blindy Aug 11 '15 at 18:31