众所周知,Rubyist import android.content.Context;
import android.os.AsyncTask;
import android.util.Pair;
import android.widget.Toast;
import com.google.api.client.extensions.android.http.AndroidHttp;
import com.google.api.client.extensions.android.json.AndroidJsonFactory;
import com.google.api.client.googleapis.services.AbstractGoogleClientRequest;
import com.google.api.client.googleapis.services.GoogleClientRequestInitializer;
import java.io.IOException;
class SendRegisterInfo extends AsyncTask<Pair<Context, String>, Void, String> {
private static MyApi myApiService = null;
private Context context;
@Override
protected String doInBackground(Pair<Context, String>... params) {
if(myApiService == null) { // Only do this once
MyApi.Builder builder = new MyApi.Builder(AndroidHttp.newCompatibleTransport(),
new AndroidJsonFactory(), null)
// options for running against local devappserver
// - 10.0.2.2 is localhost's IP address in Android emulator
// - turn off compression when running against local devappserver
.setRootUrl("http://10.0.2.2:8080/_ah/api/")
.setGoogleClientRequestInitializer(new GoogleClientRequestInitializer() {
@Override
public void initialize(AbstractGoogleClientRequest<?>
abstractGoogleClientRequest)
throws IOException {
abstractGoogleClientRequest.setDisableGZipContent(true);
}
});
// end options for devappserver
myApiService = builder.build();
}
context = params[0].first;
String name = params[0].second;
try {
return myApiService.sayHi(name).execute().getData();
} catch (IOException e) {
return e.getMessage();
}
}
@Override
protected void onPostExecute(String result) {
Toast.makeText(context, result, Toast.LENGTH_LONG).show();
}
}
会在符号上调用&
,所以
to_proc
相当于
[:a, :b, :c].map(&:to_s)
假设我想在[:a, :b, :c].map { |e| e.to_s } # => ["a", "b", "c"]
之后立即调用另一个方法,这两个实现将起作用:
to_s
我的问题是,有没有办法将[:a, :b, :c].map { |e| e.to_s.upcase }
[:a, :b, :c].map(&:to_s).map(&:upcase)
&
调用链接在一个参数中?类似的东西:
Symbol#to_proc
谢谢!
答案 0 :(得分:5)
您需要提前定义一些方法,但这将具有普遍性。你可以这样做:
class Symbol
def * other
->x{x.send(self).send(other)}
end
end
[:a, :b, :c].map(&:to_s * :upcase)
[:a, :b, :c].map(&:to_s * :capitalize)
...
我选择了*
作为功能组合的方法。
如果您认为可以使用第三个符号,则可以定义如下:
class Proc
def * other
->x{call(x).send(other)}
end
end
答案 1 :(得分:4)
如果您只是这样做:
%i[a b c].map { |e| e.to_s.upcase }
然后只需使用该块并继续处理更重要的事情。如果您真的在进行一系列可枚举的调用,并且发现这些块太过嘈杂:
%i[a b c].map { |e| e.to_s.upcase }.some_chain_of_enumerable_calls...
然后你可以把你的逻辑扔进一个lambda来帮助清理外观:
to_s_upcase = lambda { |e| e.to_s.upcase }
%i[a b c].map(&to_s_upcase).some_chain_of_enumerable_calls...
或将其扔进方法并说:
%i[a b c].map(&method(:to_s_upcase)).some_chain_of_enumerable_calls...
无论哪种方式,你都会给你的一些逻辑提供一个名称(几乎所有&:symbol
都在为你做),使代码更易读,更容易理解。在to_s.upcase
的特定情况下,这有点毫无意义,但是当块变大时,这些方法非常有用。
答案 2 :(得分:4)
所以只是为了好玩(并且为了证明几乎任何东西都可以在ruby中进行一些努力)我们可以在Symbol
上定义一个方法(我们称之为{{1} })提供此功能和更多
Symbol#chain
然后可以这样调用
class Symbol
def proc_chain(*args)
args.inject(self.to_proc) do |memo,meth|
meth, *passable_args = [meth].flatten
passable_block = passable_args.pop if passable_args.last.is_a?(Proc)
Proc.new do |obj|
memo.call(obj).__send__(meth,*passable_args,&passable_block)
end
end
end
alias_method :chain, :proc_chain
end
甚至可以单独使用
[:a, :b, :c].map(&:to_s.chain(:upcase))
#=> ["A","B","C"]
# Or with Arguments & blocks
[1,2,3,4,5].map(&:itself.chain([:to_s,2],:chars,[:map,->(e){ "#{e}!!!!"}]))
#=> => [["1!!!!"], ["1!!!!", "0!!!!"], ["1!!!!", "1!!!!"],
# ["1!!!!","0!!!!", "0!!!!"], ["1!!!!", "0!!!!", "1!!!!"]]
答案 3 :(得分:3)
虽然我们正在使用语法,但使用to_proc
方法对猴子修补数组怎么样?
class Array
def to_proc
return :itself.to_proc if empty?
->(obj) { drop(1).to_proc.call(first.to_proc.call(obj)) }
end
end
["foo", "bar", "baz"].map(&[:capitalize, :swapcase, :chars, ->a{ a.join("-") }])
# => ["f-O-O", "b-A-R", "b-A-Z"]
在repl.it上查看:https://repl.it/JS4B/1
答案 4 :(得分:1)
无法使用符号链接到proc。
但是,你可以将一个方法修补到你要映射的类上,然后调用它。
vector<A>
答案 5 :(得分:0)
我很惊讶没有人提到 Proc#<<
和 Proc#>>
:
[:a, :b, :c].map(&(:to_s.to_proc << :upcase.to_proc))
# => ["A", "B", "C"]
[:a, :b, :c].map(&(:upcase.to_proc >> :to_s.to_proc))
# => ["A", "B", "C"]