2014-01-16 5 views
0

Есть ли способ сделать эту функцию в одном выражении?Объединить два оператора с возвратом в один в Ruby

def test 
    err = _invalid_permission 
    return err if err # this statement 
    # do something else 
end 

Я пробовал:

def test 
    return (err = _invalid_permission) if err 
    # do something else 
end 

, но это отличается, err после if всегда nil

Или это один:

def test 
    return err if (err = _invalid_permission) 
    # do something else 
end 

, но это одна вызывает undefined local variable or method 'err'.

объяснение того, что я пытаюсь сделать, это сократить такого рода метод:

def test 
    err = _invalid_permission 
    return err if err 
    err = _check_another_error 
    return err if err 
    err = _and_another_one 
    return err if err 
    # and lots more 
    # do something else when not error 
    return nil 
end 

_invalid_permission, _check_another_error и _and_another_one вернется непустая строка или массив или хэш, содержащий сообщение об ошибке.

другая история, после просмотра ответов ниже, я думаю, что он может объединить в:

def test 
    err = _invalid_permission || 
    _check_another_error || 
    _and_another_one 
    # and lots more 
    return err if err 
    # do something else when not error 
    return nil 
end 
+2

Я думаю, что оригинал довольно хорош, и вы слишком беспокоитесь о преждевременной оптимизации. Другие будут проблемой чтения, и присвоение значений в условном тесте заставит меня кричать. –

+0

Явный лучше, чем неявный. – squiguy

+0

Этот код не имеет никакого смысла. Что ты пытаешься сделать? – Chuck

ответ

2
def test 
    (err = _invalid_permission) && return err 

    #do something else 
end 
+0

этот красивый. ^^ спасибо, я использую: 'err = _invalid_permission и return err' – Kokizzu

+2

@Kokizzu« Красота важнее в вычислениях, чем где-либо еще в технологии, потому что программное обеспечение настолько сложное. Красота - это максимальная защита от сложности ». - David Gelernter – robertodecurnex

1

Это работает, но вы бы пожертвовать ясностью

def test 
    (err = _invalid_permission) ? (return err) : nil 
    #do something 
end 
+1

работает, как бы странно: P – robertodecurnex

+0

код гольф всегда странный. –

1
def test 
    (err = _invalid_permission) or begin 
    # do something else 
    end 
end 
+0

, которые заставляют вас добавить остальную часть кода в виде одного предложения – robertodecurnex

1

Это Безразлично» t переходите к объединению утверждений, но если то, что вы пытаетесь сделать, это проверить множество условий ошибки, как вы показываете, это можно сделать более читаемо ч что-то вроде этого:

def test 
    err ||= _invalid_permission 
    err ||= _check_another_error 
    err ||= _and_another_one 
    return err if err 
    #do a bunch of other stuff 
end 

Или, если вы сделаете это во многих местах, это звучит как исключение может иметь смысл. Что-то вроде:

class MyValidationError < Exception 
    attr_accessor :err 
    def initialize(err) 
    @err = err 
    end 
end 

def check(err_or_nil) 
    raise MyValidationError.new(err) if err_or_nil 
end 

def test 
    check _invalid_permission 
    check _check_another_error 
    check _and_another_one 
    #do a bunch of other stuff 
rescue MyValidationError 
    $!.err 
end 

Но я думаю, что первое вполне читаемо, лично.

2

Возможно, вы задали правильный вопрос? Вы сосредоточились на одном из способов сокращения строк кода, который вы должны написать. Вместо этого вам необходимо высушить код. Вот один из способов:

module Checks 
    def _invalid_permission() nil end 
    def _check_another_error() "oops!" end 
    def _and_another_one() nil end 
end 

class Doit 
    @@checks = Checks.instance_methods(false) 
    include Checks 

    def doit 
    @@checks.each { |m| rv = send(m); return rv if rv } 

    "test" 
    end 
end 

p Doit.new.doit # => "oops!" 

Если вы изменяете

def _check_another_error() "oops!" end 

в

def _check_another_error() nil end 

затем

p Doit.new.doit # => "test" 

Этот подход также позволяет добавлять, удалять или переименовывать проверку метод без необходимости запоминать ch ange ссылается на него в другом месте.

Смежные вопросы