From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: poffice@blade.nagaokaut.ac.jp Delivered-To: poffice@blade.nagaokaut.ac.jp Received: from kankan.nagaokaut.ac.jp (kankan.nagaokaut.ac.jp [133.44.2.24]) by blade.nagaokaut.ac.jp (Postfix) with ESMTP id C099D17CE1F9 for ; Wed, 5 Nov 2014 08:29:42 +0900 (JST) Received: from funfun.nagaokaut.ac.jp (smtp.nagaokaut.ac.jp [133.44.2.201]) by kankan.nagaokaut.ac.jp (Postfix) with ESMTP id 5FFE3B5D899 for ; Wed, 5 Nov 2014 08:17:04 +0900 (JST) Received: from funfun.nagaokaut.ac.jp (localhost.nagaokaut.ac.jp [127.0.0.1]) by funfun.nagaokaut.ac.jp (Postfix) with ESMTP id 3B9A097A826 for ; Wed, 5 Nov 2014 08:17:05 +0900 (JST) X-Virus-Scanned: amavisd-new at nagaokaut.ac.jp Authentication-Results: funfun.nagaokaut.ac.jp (amavisd-new); dkim=fail (1024-bit key) reason="fail (message has been altered)" header.d=sendgrid.me Received: from funfun.nagaokaut.ac.jp ([127.0.0.1]) by funfun.nagaokaut.ac.jp (funfun.nagaokaut.ac.jp [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id bdmxYn5fFSqf for ; Wed, 5 Nov 2014 08:17:04 +0900 (JST) Received: from voscc.nagaokaut.ac.jp (voscc.nagaokaut.ac.jp [133.44.1.100]) by funfun.nagaokaut.ac.jp (Postfix) with ESMTP id CDC8997A820 for ; Wed, 5 Nov 2014 08:17:04 +0900 (JST) Received: from neon.ruby-lang.org (neon.ruby-lang.org [221.186.184.75]) by voscc.nagaokaut.ac.jp (Postfix) with ESMTP id E62C895241A for ; Wed, 5 Nov 2014 08:17:02 +0900 (JST) Received: from [221.186.184.76] (localhost [IPv6:::1]) by neon.ruby-lang.org (Postfix) with ESMTP id C4978120478; Wed, 5 Nov 2014 08:17:00 +0900 (JST) X-Original-To: ruby-core@ruby-lang.org Delivered-To: ruby-core@ruby-lang.org Received: from o10.shared.sendgrid.net (o10.shared.sendgrid.net [173.193.132.135]) by neon.ruby-lang.org (Postfix) with ESMTPS id 2702A12045E for ; Wed, 5 Nov 2014 08:16:56 +0900 (JST) DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sendgrid.me; h=from:to:references:subject:mime-version:content-type:content-transfer-encoding:list-id; s=smtpapi; bh=2cKmoY1WY275DyqPJmVPBg1VuPI=; b=ST0AUkkGqics42K6aM zRPMQst0Z4K+0SNc4erKjgnwQ8cAXTG27rq2b+at6+CLxL2TV/YYxYajLZPYg9Lh AC7XvpJBwO/zw7lxsIoeTdVUCXWWKSg6+Mk9+pBn3r2j5M4etHDdgWYqxvDYZMMX mvnEPu/16KKbcoy0fVPMLUCCo= Received: by filter0273p1mdw1.sendgrid.net with SMTP id filter0273p1mdw1.9873.54595E655 2014-11-04 23:16:53.3212697 +0000 UTC Received: from herokuapp.com (ec2-54-90-130-138.compute-1.amazonaws.com [54.90.130.138]) by ismtpd-007 (SG) with ESMTP id 1497d18bb81.755c.684c23 for ; Tue, 04 Nov 2014 23:16:53 +0000 (UTC) Date: Tue, 04 Nov 2014 23:16:53 +0000 From: gabriel.sobrinho@gmail.com To: ruby-core@ruby-lang.org Message-ID: References: Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Redmine-MailingListIntegration-Message-Ids: 40476 X-Redmine-Project: common-ruby X-Redmine-Issue-Id: 10477 X-Redmine-Issue-Author: sobrinho X-Redmine-Sender: sobrinho X-Mailer: Redmine X-Redmine-Host: bugs.ruby-lang.org X-Redmine-Site: Ruby Issue Tracking System X-Auto-Response-Suppress: OOF Auto-Submitted: auto-generated X-SG-EID: ync6xU2WACa70kv/Ymy4QrNMhiuLXJG8OTL2vJD1yS7kYCvzzW1ORtF/tuN9LKfJW8M4q509VoUPkD VN936Phhzc2D6z5KAY5Y1v2IWY1rUJdI84uMJxj272ovsbRSsEv4mSDnjycEQU7etf+3elk2Fw7V3d V4z0ZqCM3GMLlCYVUCeArMWslZNecIazExg4 X-SendGrid-Contentd-ID: {"test_id":"1415143014"} X-ML-Name: ruby-core X-Mail-Count: 66084 Subject: [ruby-core:66084] [CommonRuby - Feature #10477] [Open] Implicit interfaces X-BeenThere: ruby-core@ruby-lang.org X-Mailman-Version: 2.1.15 Precedence: list Reply-To: Ruby developers List-Id: Ruby developers List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: ruby-core-bounces@ruby-lang.org Sender: "ruby-core" Issue #10477 has been reported by Gabriel Sobrinho. ---------------------------------------- Feature #10477: Implicit interfaces https://bugs.ruby-lang.org/issues/10477 * Author: Gabriel Sobrinho * Status: Open * Priority: Normal * Assignee: * Category: * Target version: ---------------------------------------- Hello guys, I would to suggest us to discuss about implementing implicit interfaces on Ruby like Go. > Go does not have classes. However, you can define methods on struct types. The method receiver appears in its own argument list between the func keyword and the method name. This means you can specify a implicit interface where the implementation packages and packages that define the interfaces neither depends on the other. That keeps the concept of duck typing but adds a extra layer of interface security to the language instead of relying on `NoMethodError` exceptions. Go usage example: ``` go type Vertex struct { X, Y float64 } func (v *Vertex) Abs() float64 { return math.Sqrt(v.X*v.X + v.Y*v.Y) } ``` In Ruby it could something like that: ``` ruby interface Cache def get(key, default = nil) def set(key, value, ttl = nil) def delete(key) end class App def initialize(cache_store Cache) @cache_store = cache_store end delegate :get, :set, :delete, :to => :@cache_store end ``` In this case a `NoMethodError` would never occur on `App#get`, `App#set` and `App#delete`. If you think about service objects, you may have things like that: ``` ruby class Buy def self.finish(object) object.store( fine: FineCalculator.calculate(object.value, Date.current) interest: InterestCalculator.calculate(object.value, Date.current) expedient: ExpedientCalculator.calculate(object.value, Date.current) ) BuyMailer.deliver(to: object.buyer, object: object) end end ``` In a case of a failure on calling `object.buyer`, the `object.store` has already happened and may affect the system in a bad way, which may not be acceptable. Using a implicit interface it would never happen: ``` ruby interface Purchasable def store(attrs) def value def buyer end class Buy def self.finish(object Purchasable) object.store( fine: FineCalculator.calculate(object.value, Date.current) interest: InterestCalculator.calculate(object.value, Date.current) expedient: ExpedientCalculator.calculate(object.value, Date.current) ) BuyMailer.deliver(to: object.buyer, object: object) end end ``` I think it's a great idea of Go that would be of benefit in Ruby. Probably there is better usage cases, sorry about that, but the concept is to have implicit interfaces on libraries that we publish for everyone (gems). Think about complex interfaces like [capybara drivers](https://github.com/jnicklas/capybara/blob/master/lib/capybara/driver/base.rb), [active support cache drivers](https://github.com/rails/rails/blob/master/activesupport/lib/active_support/cache.rb#L484-L500) and etc. How it sounds? _Reference: http://programmers.stackexchange.com/questions/197356/how-does-go-improve-productivity-with-implicit-interfaces-and-how-does-that-c_ -- https://bugs.ruby-lang.org/