2014-01-30 85 views
0

我试图实现一个时髦的版本的方法链接。每个函数调用后返回的类的实例很容易,你只是做在ruby中返回包含对象实例

def chainable_method 
    some_code() 
    self 
end 

我的想法是,你可以调用的方法依赖于以前的方法调用。我试图通过返回属于包含对象的对象来实现此目的。包含的对象将有一些特殊的方法,然后实现method_missing返回包含对象的实例。

编辑:子对象有一些与它相关的状态,应该在其本身,而不是父对象。以前可能并不清楚为什么我只需要一个完整的方法调用实例。

super在这种情况下是不相关的,因为包含的对象不会从包含对象继承,我不想在包含的对象上调用包含对象的方法 - 我想调用包含对象的方法包含对象本身。我想要包含的对象,而不是包含的对象类。

不知道这是否可能。

编辑:重写所有使用“包含/包含对象”而不是完全不正确的父/子对象。 另外,我使用1.9.3,如果这很重要。版本不重要,如果需要,我可以更改。

我的解释可能不清楚。这里是代码:

class AliasableString 
    def initialize(string) 
     @string = string 
    end 

    def as(aka) 
     @aka = aka 
    end 

    def has_aka? 
     [email protected]? 
    end 

    # alias is a reserved word 
    def aka 
     @aka 
    end 

    def to_s 
     @string + (self.has_aka? ? (" as " + @aka) : "") 
    end 
end 

class Query 
    def initialize 
     @select_statements = Array.new 
    end 

    def select(statement) 
     select_statement = AliasableString.new(statement) 
     @select_statements.push(select_statement) 
     select_statement 
    end 

    def print 
     if @select_statements.size != 0 
      puts "select" 
      @select_statements.each_with_index {| select, i| 
       puts select 
      } 
     end 
    end 
end 

# Example usage 

q0 = Query.new 

q0.select("This is a select statement") 
    .select("Here's another one") 
     .as("But this one has an alias") 
    .select("This should be passed on to the parent!") 

q0.print 

我还没有完全实现打印。 AliasableString需要将@string和@aka分开,以便稍后将它们分开。

+0

发布父类和子类。 – jcm

+0

没有“父实例”。只有实例。要么你想返回'Parent.new'或者你有一个父实例,并且可以返回它。 – mudasobwa

+0

'子对象不会继承父'''我想要父实例,而不是父类'... wat。 – jkrmr

回答

2

首先,在Query实例中包含哪类对象并不重要。在“示例用法”部分中显示的所有语法在Query中进行了适当的定义。查询实例中包含的对象的唯一要求是它们响应as(或某种类似的方法)。你在这里有什么像状态机,但唯一真正重要的状态是某个对象占据了select_statements阵列中的最后一个位置。这是我会怎么构建这个(再次,主要基于在结束你的榜样,我恐怕不能完全按照你最初的解释):

class Query 
    # ... initialize, etc. 

    def select(statement, statement_class = AliasableString) 
    select_statements << statement_class.new(statement) 
    self 
    end 

    def as(aka) 
    # this will only ever be used on the most recent statement added 
    statement_to_alias = select_statements.last 

    # throw an error if select_statements is empty (i.e., :last returns nil) 
    raise 'You must add a statement first' unless statement_to_alias 

    # forward the message on to the statement 
    statement_to_alias.as(aka) 

    # return the query object again to permit further chaining 
    self 
    end 
end 

AliasableString并不需要知道有关的事Query;它所需要做的就是对as作出适当的回应。

+0

这是有效的,它比我能想出的任何其他选项更有意义/更简单。我会去这个。谢谢! 我可以看到的唯一问题是,如果多个对象同时在一个查询上运行(例如,使用线程),这可能会中断,但我的最终目标只是自动生成真正重复的HiveQL查询。我不可能想到任何真实的生活情况,这将成为一个问题。 –

相关问题