# Ruby 的 heredoc 與 eval

来源:https://www.cnblogs.com/xhyccc/archive/2023/02/21/17142907.html
-Advertisement-
Play Games

在如 rails 這樣的開源庫中,我們常常見到這樣的一類寫法: class_eval <<-RUBY, lxx_file, lxx_line + 1 def xxx # do something here end RUBY 令人困惑不已。 不過這裡的知識點非常簡單,只要掌握了 heredoc 與 e ...


在如 rails 這樣的開源庫中,我們常常見到這樣的一類寫法:

class_eval <<-RUBY, __FILE__, __LINE__ + 1
  def xxx
    # do something here
  end
RUBY

令人困惑不已。

不過這裡的知識點非常簡單,只要掌握了 heredoc 與 eval 的用法,就很好理解這裡的代碼了。

heredoc

heredoc 是一種定義多行字元串的方法,同時保持原始縮進和格式。相當於 JavaScript 中的 ``。

heredoc 以 <<- 開頭,跟上一個隨意的單詞,最後再以這個字元串結束:

multi_str = <<-FOO
1
  2
    3
FOO

puts multi_str

多行字元串會保留所有的縮進,並且在尾部會帶上 \n 換行符。

對於換行符,可以使用 chomp 來去除:<<-FOO.chomp

如果你在縮進的情況下聲明 heredoc,可能會變成這樣,十分醜陋:

    multi_str = <<-FOO
1
  2
    3
    FOO

如果保持縮進:

    multi_str = <<-FOO
    1
      2
        3
    FOO

最後的輸出結果也會帶上 1 所有縮進,這裡可以使用 ~ 代替 -,或是使用 strip

    multi_str = <<~FOO
    1
      2
        3
    FOO
    multi_str = <<-FOO.strip
    1
      2
        3
    FOO

這兩種方式都會以第一行為標準,在所有行的開頭,刪除空格。

eval

eval 在很多腳本語言中都存在,它可以讓我們將字元串作為代碼執行。

ruby 中存在多個 eval 方法,比如 eval class_eval module_eval instance_eval 等。

他們分別可以實現不同的 eval 功能。

class_eval 為例:

class Foo
  STR = <<-RUBY
    def say
      p 'I am Foo'
    end
  RUBY

  Module.class_eval STR
end

Foo.say

我們可以輕鬆將字元串變成方法。

代碼分析

現在我們終於可以看懂這段代碼了,它其實就是使用了 heredoc 多行字元串,將字元串里變成了一個真正的 ruby 方法。

class_eval <<-RUBY, __FILE__, __LINE__ + 1
  def xxx
    # do something here
  end
RUBY

那麼後面的 __FILE__, __LINE__ + 1 有什麼用呢?

其實我們完全可以不傳這兩個參數。

但是加入我們字元串生成的方法報了錯該怎麼辦呢?一般我們的方法報錯都會有文件名、行號。

eval 使用字元串生成方法,自然沒有這些東西,所以我們傳入當前文件的文件名,和當前行的行號+1,來幫助 Ruby 生成更好的報錯信息。

(完)

作者:幾乎一米八的徐某某 出處:Aero Blog (https://www.cnblogs.com/xhyccc/) 本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須在文章頁面給出原文連接,否則保留追究法律責任的權利。
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 字元串 substring 形式:substring(index1, index2) 不會改變原始字元串 將小的參數作為開始位置 start,大的作為結束位置 stop 包含 start,但不包含 stop 如果只給一個參數表示從它 start 截取到字元串結尾 如果某個參數為負,會先將負數變為 0 ...
  • 二進位和八進位表示法 ES6提供了二進位和八進位數值的新的寫法,分別用首碼0b(或0B)和0o或(0O)表示 0b111110111 503 // true; 0o767 503; // true 在es5開始,嚴格模式中,八進位不允許使用首碼0 表示,否則會報錯 // 嚴格模式 (function ...
  • 代碼組織 代碼按一下順序組織: @import 變數聲明 樣式聲明 1 @import "mixins/size.less"; 2 @default-text-color: #333; 3 .page { 4 width: 960px; 5 margin: 0 auto; 6 } @import 語 ...
  • vue2 使用 cesium 篇 今天好好寫一篇哈,之前寫的半死不活的。首先說明:這篇博文是我邊做邊寫的,小白也是,實現效果會同時發佈截圖,如果沒有實現也會說明,僅僅作為技術積累,選擇性分享,不做教學哈。不好別噴。 安裝 cesium 這個就很簡單,只需要一句簡簡單單的命令就可以實現在 vue 項目 ...
  • 本文是系列第二篇。系列文章: 現代圖片性能優化及體驗優化指南 - 圖片類型及 Picture 標簽的使用 圖片資源,在我們的業務中可謂是占據了非常大頭的一環,尤其是其對帶寬的消耗是十分巨大的。 對圖片的性能優化及體驗優化在今天就顯得尤為重要。本文,就將從各個方面闡述,在各種新特性滿頭飛的今天,我們可 ...
  • 一、背景 遠程服務將電腦程式的工作範圍從單機擴展到網路,從本地延伸至遠程,是構建分散式系統的首要基礎。遠程服務調用(Remote Procedure Call,RPC)在電腦科學中已經存在了超過四十年時間。但很多人無法明確區分RPC與Rest。本文就講一講RPC和Rest的本質區別。 二、分析 ...
  • 談到java中的併發,我們就避不開線程之間的同步和協作問題,談到線程同步和協作我們就不能不談談jdk中提供的AbstractQueuedSynchronizer(翻譯過來就是抽象的隊列同步器)機制; (一)、AQS中的state和Node含義: AQS中提供了一個int volatile state ...
  • RabbitMQ 配置環境 安裝 erlang環境以及RabbitMQ RabbitMQ埠號: 5672 去官網下載 https://www.rabbitmq.com 然後重啟RabbitMQ服務 RabbitMQ安裝教程 開放埠15672 這裡,通過http://IP地址:15672 進行We ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...