我运行了 rbenv versions
(用 ssh 登陆),显示只有 system
,是不是只有“系统带的那个版本”
我用管理员用户安装的 ruby3.3.0,找不到
打印了 /usr/bin/ruby
然后,,,我还是不知道怎么解决,,,可以麻烦详细介绍一下吗,非常感谢
把 vue 归到保姆式框架,感觉有点不合适 虽然它肯定比 react 更保姆式
字体调小一点,效果更佳,但对眼镜不好
em,,,,,,互弟,互弟
把电子书阅读器(我用的 kindle,免费),调成暗色,跟代码编辑器一毛一样
如果决定要做 ruby,想系统学习,建议看《ruby 基础教程》
如果只是想试试,可以:
也是,,,
小弟我平时其实会看些电子书,最近在看《过得刚好》
bilibili 是全国最优秀的学习网站你不知道?
如果需要的功能少,可以不用 sdk,原理很简单,就是发几条 http 请求
或者可以学习视频字幕,在任何画面下都很清晰,但颜色很单一:
刘明
最新的不是 07 年的吗……
// 把带有pid的数组转化成tree结构数据(只用一次循环)
// 以顶级的pid为-1为例
// 本例假设只有一个跟结点(如果有多个根结点,建议把这些根节点跟在一个虚拟的根结点上)
function treefy(arr){
var home={};
var dad;
arr.forEach(function(item){
//把自己放家里
if(home[item.id]){ // 如果发现有人顶替老子
item.children=home[item.id].children; // 那得把儿子们领回来
}else{
item.children=[]; // 没有人顶替老子,也得给儿子们准备个地儿
}
home[item.id]=item; // 然后进家
//把自己放到爸爸那里
if(!home[item.pid]) //如果爸爸不在家
home[item.pid]={ // 就造个爸爸
children: []
};
home[item.pid].children.push(item); // 找到爸爸!
});
return home[-1];
}
var testData=[
{
id: 1,
name: 'id1',
pid: -1
},{
id: 2,
name: 'id2',
pid: 1
},{
id: 3,
name: 'id3',
pid: 2
},{
id: 4,
name: 'id4',
pid: 5
},{
id: 5,
name: 'id5',
pid: 1
}
];
console.log(treefy(testData))
存在多对多的话,可以再建一个“关系表”,比如“多级的用户”可以这样:
(用户表)
| id | name |
| ---- | ---- |
| 1 | 小明 |
| 2 | 小红 |
| 3 | 小华 |
加入它们三个互为上级,则可以(关系表): | user_id | super_id | | ---- | ---- | | 1 | 2 | | 1 | 3 | | 2 | 1 | | 2 | 3 | | 3 | 1 | | 3 | 2 |
认真的吗,,,,,我觉得《元编程》还是有难度的啊
嘿嘿,我让朋友买了我看的那本,我买了你说的那本
刚刚买了一本~
我有元编程那本,两年多前买的,直到...今年春节才看的,不过感觉非常好 但是第一本有点老了,我看淘宝上都是 2007 年的版本
做 ios 的
结帖了结帖了,感谢!
感谢指点,用 bundler 怎么自动安装项目 A 的依赖呢
我来翻译一下哈哈。 有一群小伙伴喜欢漫威,这群小伙伴搞了个论坛,方便大家在里面讨论漫威。 有一天,这个论坛倒闭了。 问:漫威在中国凉透了吗?还是说漫威凉透了?
共勉~
翻译了一篇关于OptionParser
的文档,共勉。
原文链接
OptionParser
是一个用于“解析命令行参数”的类。和 GetoptLong相比,它功能更丰富,使用起来更简单,并且是一种更具 Ruby 风格的解决方案。
译者注:GetoptLong 和 OptionParser 功能类似,但偏向 C 语言风格
所有的这些特性将在下面的例子中演示。详参mack_switch
require 'optparse'
options = {}
OptionParser.new do |opts|
opts.banner = "Usage: example.rb [options]"
opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
options[:verbose] = v
end
end.parse!
p options
p ARGV
OptionParser
可以自动生成“帮助”文档,来介绍你写的命令:
require 'optparse'
Options = Struct.new(:name)
class Parser
def self.parse(options)
args = Options.new("world")
opt_parser = OptionParser.new do |opts|
opts.banner = "Usage: example.rb [options]"
opts.on("-nNAME", "--name=NAME", "Name to say hello to") do |n|
args.name = n
end
opts.on("-h", "--help", "Prints this help") do
puts opts
exit
end
end
opt_parser.parse!(options)
return args
end
end
options = Parser.parse %w[--help]
#=>
# Usage: example.rb [options]
# -n, --name=NAME Name to say hello to
# -h, --help Prints this help
译者注: 有的参数不需要值,比如
--help
,一般用来查看一个命令的使用方法 有的参数必须有值,比如登录 mysql,填写用户名:mysql -uUSERNAME
对于那些必须有值的参数,“参数说明字符串”里需要包含大写的“参数名”。如果使用一个“必须有值的参数”,但未传入值时,将会抛出一个异常。
require 'optparse'
options = {}
OptionParser.new do |parser|
parser.on("-r", "--require LIBRARY",
"Require the LIBRARY before executing your script") do |lib|
puts "You required #{lib}!"
end
end.parse!
使用:
$ ruby optparse-test.rb -r
optparse-test.rb:9:in `<main>': missing argument: -r (OptionParser::MissingArgument)
$ ruby optparse-test.rb -r my-library
You required my-library!
OptionParser
可以把参数值转化成某个对象。
OptionParser
附带了一些开箱即用的类型转化,它们是:
Date
- 所有 Date.parse
接受的东西DateTime
- 所有 DateTime.parse
接受的东西Time
- 所有 Time.httpdate
或 Time.parse
接受的东西URI
- 所有 URI.parse
接受的东西Shellwords
- 所有 Shellwords.shellwords
接受的东西String
- 所有的非空字符串Integer
- 所有整数。将转化八进制。(比如:124、-3、040)Float
- 所有浮点型数。(比如:10、3.14、-100E+13)Numeric
- 所有整数、浮点型数、有理数。(比如:1、3.4、1/3)DecimalInteger
- 类似 Integer,但不支持八进制。OctalInteger
- 类似 Integer,但不支持十进制。DecimalNumeric
- 十进制整数或浮点型数。TrueClass
- 接受 true
、false
、yes
、no
、+
、-
,默认值是 true
FalseClass
- 跟 TrueClass
一样,但默认值是 false
Array
- 被逗号分开的字符串。(比如:1,2,3)Regexp
- 正则表达式。也包括参数。我们也可以添加自己的类型转化,详见下文。
作为一个例子,这里使用内置的 Time
转化。其他内置的转化,也是一样的。OptionParser
会把这个参数当作一个 Time 来解析。如果成功了,这个 Time 对象被传给“处理块”(handle block)。否则会抛出一个异常。
require 'optparse'
require 'optparse/time'
OptionParser.new do |parser|
parser.on("-t", "--time [TIME]", Time, "Begin execution at given time") do |time|
p time
end
end.parse!
使用:
$ ruby optparse-test.rb -t nonsense
... invalid argument: -t nonsense (OptionParser::InvalidArgument)
$ ruby optparse-test.rb -t 10-11-12
2010-11-12 00:00:00 -0500
$ ruby optparse-test.rb -t 9:30
2014-08-13 09:30:00 -0400
OptionParser
上的 accept
方法用于创建“转化”。它声明“某个类的转化块(conversion block)”。下面的例子使用它(accept)来获取一个 User 对象,在 on
处理器(on
handler)接收到它之前。
require 'optparse'
User = Struct.new(:id, :name)
def find_user id
not_found = ->{ raise "No User Found for id #{id}" }
[ User.new(1, "Sam"),
User.new(2, "Gandalf") ].find(not_found) do |u|
u.id == id
end
end
op = OptionParser.new
op.accept(User) do |user_id|
find_user user_id.to_i
end
op.on("--user ID", User) do |user|
puts user
end
op.parse!
使用:
$ ruby optparse-test.rb --user 1
#<struct User id=1, name="Sam">
$ ruby optparse-test.rb --user 2
#<struct User id=2, name="Gandalf">
$ ruby optparse-test.rb --user 3
optparse-test.rb:15:in `block in find_user': No User Found for id 3 (RuntimeError)
order
、parse
等方法的 into
参数用来存储命令行参数到一个 Hash
。
require 'optparse'
params = {}
OptionParser.new do |opts|
opts.on('-a')
opts.on('-b NUM', Integer)
opts.on('-v', '--verbose')
end.parse!(into: params)
p params
使用:
$ ruby optparse-test.rb -a
{:a=>true}
$ ruby optparse-test.rb -a -v
{:a=>true, :verbose=>true}
$ ruby optparse-test.rb -a -b 100
{:a=>true, :b=>100}
下面的例子是一个完整的 Ruby 程序。你可以运行它,然后观察各种参数的效果。这也许是学习 optparse
的特性的最佳途径。
require 'optparse'
require 'optparse/time'
require 'ostruct'
require 'pp'
class OptparseExample
Version = '1.0.0'
CODES = %w[iso-2022-jp shift_jis euc-jp utf8 binary]
CODE_ALIASES = { "jis" => "iso-2022-jp", "sjis" => "shift_jis" }
class ScriptOptions
attr_accessor :library, :inplace, :encoding, :transfer_type,
:verbose, :extension, :delay, :time, :record_separator,
:list
def initialize
self.library = []
self.inplace = false
self.encoding = "utf8"
self.transfer_type = :auto
self.verbose = false
end
def define_options(parser)
parser.banner = "Usage: example.rb [options]"
parser.separator ""
parser.separator "Specific options:"
# add additional options
perform_inplace_option(parser)
delay_execution_option(parser)
execute_at_time_option(parser)
specify_record_separator_option(parser)
list_example_option(parser)
specify_encoding_option(parser)
optional_option_argument_with_keyword_completion_option(parser)
boolean_verbose_option(parser)
parser.separator ""
parser.separator "Common options:"
# No argument, shows at tail. This will print an options summary.
# Try it and see!
parser.on_tail("-h", "--help", "Show this message") do
puts parser
exit
end
# Another typical switch to print the version.
parser.on_tail("--version", "Show version") do
puts Version
exit
end
end
def perform_inplace_option(parser)
# Specifies an optional option argument
parser.on("-i", "--inplace [EXTENSION]",
"Edit ARGV files in place",
"(make backup if EXTENSION supplied)") do |ext|
self.inplace = true
self.extension = ext || ''
self.extension.sub!(/\A\.?(?=.)/, ".") # Ensure extension begins with dot.
end
end
def delay_execution_option(parser)
# Cast 'delay' argument to a Float.
parser.on("--delay N", Float, "Delay N seconds before executing") do |n|
self.delay = n
end
end
def execute_at_time_option(parser)
# Cast 'time' argument to a Time object.
parser.on("-t", "--time [TIME]", Time, "Begin execution at given time") do |time|
self.time = time
end
end
def specify_record_separator_option(parser)
# Cast to octal integer.
parser.on("-F", "--irs [OCTAL]", OptionParser::OctalInteger,
"Specify record separator (default \\0)") do |rs|
self.record_separator = rs
end
end
def list_example_option(parser)
# List of arguments.
parser.on("--list x,y,z", Array, "Example 'list' of arguments") do |list|
self.list = list
end
end
def specify_encoding_option(parser)
# Keyword completion. We are specifying a specific set of arguments (CODES
# and CODE_ALIASES - notice the latter is a Hash), and the user may provide
# the shortest unambiguous text.
code_list = (CODE_ALIASES.keys + CODES).join(', ')
parser.on("--code CODE", CODES, CODE_ALIASES, "Select encoding",
"(#{code_list})") do |encoding|
self.encoding = encoding
end
end
def optional_option_argument_with_keyword_completion_option(parser)
# Optional '--type' option argument with keyword completion.
parser.on("--type [TYPE]", [:text, :binary, :auto],
"Select transfer type (text, binary, auto)") do |t|
self.transfer_type = t
end
end
def boolean_verbose_option(parser)
# Boolean switch.
parser.on("-v", "--[no-]verbose", "Run verbosely") do |v|
self.verbose = v
end
end
end
#
# Return a structure describing the options.
#
def parse(args)
# The options specified on the command line will be collected in
# *options*.
@options = ScriptOptions.new
@args = OptionParser.new do |parser|
@options.define_options(parser)
parser.parse!(args)
end
@options
end
attr_reader :parser, :options
end # class OptparseExample
example = OptparseExample.new
options = example.parse(ARGV)
pp options # example.options
pp ARGV
在一些现代化 Shell 中(例如 bash、zsh 等),你可以使用“命令自动补全”来完成参数输入。(译者注:tab 键)
上面的例子应该足够教会你使用这个类。如果有问题,去 bugs.ruby-lang.org。
好的~
感谢 @Rei 的提示,发现了 OptionParser
感觉把 OptionParser
提供的功能用一下,就 ok 了
感谢!