簡體   English   中英

如何在不需要Thor CLI應用程序的情況下使用Thor操作?

[英]How do I use Thor actions without requiring a Thor CLI app?

Thor :: Actions( http://textmate.rubyforge.org/thor/Thor/Actions.html )有一些很棒的幫助方法我想訪問但是如果不使用Thor CLI應用程序我似乎無法使用它們。

我試過簡單地說:

require "rubygems"
require "thor"

Thor::Actions.create_file "foo.txt", "contents"

哪個投擲:

run.rb:4:in '<main>': undefined method 'create_file' for Thor::Actions:Module (NoMethodError)

我意識到我可能會遺漏一些非常簡單的東西。 謝謝。

Thor打算讓你的類繼承Thor類。 然后Thor類包含並擴展模塊,允許它們的方法成為類方法。 如果您查看源代碼,例如Actions.rb ,您將看到我的意思:

# thor/lib/thor/actions.rb

class Thor
  module Actions

    # this is the interesting part and answers your question
    def self.included(base) #:nodoc:
      base.extend ClassMethods
    end

    module ClassMethods

這是一個常見的Ruby習語,它使用mixin在其包含器上定義類方法(而不是實例方法)。

舉個例子,

[2] pry(main)> class Klass
[2] pry(main)*   module Mod  
[2] pry(main)*     def self.included(base)    
[2] pry(main)*       base.extend ClassMethods      
[2] pry(main)*     end  
[2] pry(main)*     module ClassMethods    
[2] pry(main)*       def act_as_class_method      
[2] pry(main)*         puts "Im a class method now!!!"        
[2] pry(main)*       end  
[2] pry(main)*     end  
[2] pry(main)*   end  
[2] pry(main)* end  
=> nil

現在打電話

Klass::Mod.act_as_class_method

導致你遇到同樣的錯誤

NoMethodError: undefined method `act_as_class_method' for Klass::Mod:Module
from (pry):26:in `__pry__'

但是如果你ClassMethod Klassinclude Klass::Mod那么included回調會extends ClassMethod模塊,讓你使用ClassMethods定義的方法作為類方法

[4] pry(main)> class Example < Klass
[4] pry(main)*   include Klass::Mod

[4] pry(main)*   self.act_as_class_method
[4] pry(main)* end  

=> Im a class method now!!!
=> nil

這花了我一段時間才弄清楚,所以不要感覺不好,不要,它不是那么簡單或明顯。

要在不繼承Thor情況下使用Thor::Actions

class Builder # or whatever
  # To get your hands on the `from_superclass` method
  include Thor::Base

  # What we're interested in…
  include Thor::Actions
  source_root "/path/to/where/things/come/out"

  def initialize(*)
    # whatever you might want to do
    @destination_stack = [self.class.source_root]
  end
end

希望別人覺得這很有用。 用Thor v0.18.1進行測試和測試; 因為這是內部API的東西,它可能會在未來的某個時刻打破。

然后,您可以在Builder類中使用輔助方法,如下所示:

class Builder
  def build
    in_root { 'do things' }
    create_file 'etc'
  end
end

編輯:如果要控制創建文件和文件夾的位置,則需要設置destination_root如下所示:

class Builder
  include Thor::Base
  include Thor::Actions
  source_root Dir.pwd

  def initialize(root)
    self.destination_root = File.expand_path(root)
  end

  def build
    directory 'templates', 'target'
  end
end

我自己是Thor的新手,但我不認為它是獨立工作的。

嘗試在內部創建Thor任務,然后啟動它。

這是我嘗試過的一個例子,放在一個名為thor_createfile.rb的文件中(我已經添加了一些其他的東西,我將在代碼之后解釋,這可能對你很有啟發性):

#!/usr/bin/env ruby

require 'rubygems'    
require 'thor'

class MyThorTasks < Thor
  include Thor::Actions

  default_task :createInflexibleFile

  desc "createFile <fname> <content>", "Creates a file with some content"
  def createFile(fname, content)
    create_file fname, content
  end

  INFLEXIBLE_FILENAME = "the_filename.txt"
  INFLEXIBLE_CONTENT = "Greetings, Earthlings!"

  desc "createInflexibleFile", "Creates a file called '#{INFLEXIBLE_FILENAME}' containing '#{INFLEXIBLE_CONTENT}'"
  def createInflexibleFile
    puts "Creating a file called '#{INFLEXIBLE_FILENAME}' containing '#{INFLEXIBLE_CONTENT}'"
    create_file INFLEXIBLE_FILENAME, INFLEXIBLE_CONTENT
  end
end

MyThorTasks.start

您可以看到它定義了一個擴展Thor的類,然后在其上調用start方法。

現在你應該能夠像這樣簡單地調用它:

./thor_createfile.rb

它將使用指定為default_task的任務。

但是,如果需要使用某些命令行參數,則可以按名稱顯式調用任務。 所以要調用其他任務,例如:

./thor_createfile.rb createFile fancy_file_name.txt "Text to go inside the file"

注意我告訴它include Thor::Actions所以你感興趣的所有項目(比如create_file )都可用。

現在你可以在其中添加其他任務(確保為每個任務添加desc ,否則它可能會抱怨)並根據需要使用它們。

要讓它告訴你里面定義的所有任務,你可以這樣調用它:

./thor_createfile.rb -?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM