2016-11-05 36 views
1

我想插入一個instance_eval字符串中的值。參數alias_name有時可以是零或字符串。如果是零,那麼我調用它返回一個字符串的另一種方法,如下圖所示:語法錯誤,意外|| in instance_eval字符串

def create_document(klass, alias_name) 
    klass.instance_eval <<-EOS 
     def alias_name 
     #{alias_name} || name 
     end 
    EOS 
end 

但是,這實際上是給了我一個語法錯誤:

Uncaught exception: (eval):2: syntax error, unexpected || 
     || name 
     ^

我這個代碼密切關注我沒有看到語法錯誤。如果#{alias_name}要麼返回零或字符串,爲什麼這會導致錯誤?

畢竟這所有的作品:

> nil || 'something else' 
=> "something else" 
> 'something' || 'something else' 
=> "something" 

alias_name是零,它不會在所有的評估。它就像instance_eval字符串中的非易失性一樣,導致語法錯誤。但是,即使這不工作:

alias_name = alias_name || "" 
klass.instance_eval <<-EOS 
    def alias_name 
    if #{alias_name}.present? 
     #{alias_name} 
    else 
     demodulized_name 
    end 
    end 
EOS 

它將給這個錯誤:

Uncaught exception: (eval):2: syntax error, unexpected '.' 
     if .present? 
      ^

你看到了嗎?其彷彿alias_name不存在。

+1

它的問題,這樣,使'eval'一個棘手的和潛在的非常危險的工具。只要有可能,試着用'define_method'系統和'send(alias_name)'來做這件事。 – tadman

回答

2

當使用字符串插值,"s #{expr} s"等效於:

's ' + expr.to_s + ' s' 

nil.to_s是一個空字符串,所以這樣的:

klass.instance_eval <<-EOS 
    def alias_name 
    #{alias_name} || name 
    end 
EOS 

結束等:

klass.instance_eval %q{ 
    def alias_name 
    || name 
    end 
} 

alias_namenil或空s tring和:

def alias_name 
    || name 
end 

在語法上不是正確的Ruby代碼。

,你餵養klass.instance_eval不知道有任何特殊的定界符「這是Ruby代碼」上下文,它只是建立一個字符串像任何其他字符串,一味呼籲#{}插值to_s

也許你想使用inspect而不是to_s

klass.instance_eval <<-EOS 
    def alias_name 
    #{alias_name.inspect} || name 
    end 
EOS 

這會給你的Ruby代碼,如:

def alias_name 
    nil || name 
end 

alias_namenil和:

def alias_name 
    "pancakes" || name 
end 

alias_name是字符串'pancakes'

或者你想要的instance_eval如果alias_name外測試的目的是另一種方法的名稱:

if alias_name.present? 
    klass.instance_eval <<-EOS 
    def alias_name 
     #{alias_name} || name 
    end 
    EOS 
else 
    klass.instance_eval <<-EOS 
    def alias_name 
     name 
    end 
    EOS 
end 
+0

有趣的是,我從來沒有真正理解to_s的區別,並在此之前進行檢查。 – Donato

相關問題