我最近试图启动iex。我在shell中键入using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
namespace Migratable {
[JsonConverter(typeof(MigratableConverter))]
public interface IMigratable {
}
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
public class MigratableAttribute : Attribute {
public readonly Guid Id;
public MigratableAttribute(string guid) {
Id = Guid.Parse(guid);
}
}
public class MigratableConverter : JsonConverter {
[ThreadStatic]
static bool writeDisabled = false;
[ThreadStatic]
static bool readDisabled = false;
public override bool CanRead => !readDisabled;
public override bool CanWrite => !writeDisabled;
public override bool CanConvert(Type objectType) => typeof(IMigratable).IsAssignableFrom(objectType);
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) {
try {
writeDisabled = true;
if (null == value) {
writer.WriteValue(value);
} else {
var jObject = JObject.FromObject(value);
jObject.Add("$typeId", MigratableTypes.GetTypeId(value.GetType()));
jObject.WriteTo(writer);
}
} finally {
writeDisabled = false;
}
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) {
try {
readDisabled = true;
var jObject = JToken.ReadFrom(reader) as JObject;
if (null == jObject) return null;
var typeId = (Guid)jObject.GetValue("$typeId");
var type = MigratableTypes.GetType(typeId);
return JsonConvert.DeserializeObject(jObject.ToString(), type);
} finally {
readDisabled = false;
}
}
}
internal static class MigratableTypes {
static readonly Dictionary<Guid, Type> Data = new Dictionary<Guid, Type>();
static MigratableTypes() {
foreach (var type in GetIMigratableTypes()) {
CheckIMigratableRules(type);
Data[GetTypeId(type)] = type;
}
}
static IEnumerable<Type> GetIMigratableTypes() {
return AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(a => a.GetTypes()
.Where(t => typeof(IMigratable).IsAssignableFrom(t))
.Where(t => !t.IsAbstract));
}
static void CheckIMigratableRules(Type type) {
// Check for duplicate IMigratable identifiers
var id = GetTypeId(type);
if (Data.ContainsKey(id))
throw new Exception($"Duplicate '{nameof(MigratableAttribute)}' value found on types '{type.FullName}' and '{Data[id].FullName}'.");
// [DataContract] attribute is required, on EVERY class, not just base classes
if (type.GetCustomAttributes(typeof(DataContractAttribute), false).Length == 0)
throw new Exception($"'{nameof(IMigratable)}' objects are required to use the '[DataContract]' attribute. Class: '{type.FullName}'.");
// Collect information about [DataMember] attributes on all fields and properties including inherited and private.
var bindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
var fields = type.GetFields(bindingFlags).Where(f => null != f.GetCustomAttribute(typeof(DataMemberAttribute))).ToArray();
var properties = type.GetProperties(bindingFlags).Where(p => null != p.GetCustomAttribute(typeof(DataMemberAttribute))).ToArray();
var members = fields.Cast<MemberInfo>().Concat(properties.Cast<MemberInfo>())
.Select(m => new {
Member = m,
DataMemberAttribute = (DataMemberAttribute)m.GetCustomAttribute(typeof(DataMemberAttribute))
}).ToArray();
// Check that DataMember names are explicitly set eg [DataMember(Name = "xx")]
var noName = members.FirstOrDefault(m => !m.DataMemberAttribute.IsNameSetExplicitly);
if (null != noName) {
var message = $"'{nameof(IMigratable)}' objects are required to set DataMember names explicitly. Class: '{type.FullName}', Field: '{noName.Member.Name}'.";
throw new Exception(message);
}
// Check that DataMember names are not accidentally duplicated.
var duplicateName = members.GroupBy(m => m.DataMemberAttribute.Name).FirstOrDefault(g => g.Count() > 1);
if (null != duplicateName) {
throw new Exception($"Duplicate DataMemberName '{duplicateName.Key}' found on class '{type.FullName}'.");
}
}
public static Type GetType(Guid typeId) {
return Data[typeId];
}
public static Guid GetTypeId(Type type) {
var a = type.GetCustomAttributes(typeof(MigratableAttribute), false)
.Cast<MigratableAttribute>()
.FirstOrDefault();
if (null == a)
throw new Exception($"'{nameof(MigratableAttribute)}' attribute does not exist on type '{type.FullName}'.");
if (Guid.Empty == a.Id)
throw new Exception($"'{nameof(MigratableAttribute)}' attribute was not set to a proper value on type '{type.FullName}'.");
return a.Id;
}
}
}
(我尝试了几个shell,以防万一)并且iex没有提供任何提示等。它只是坐在那里,如果我键入像箭头一样的特殊键,它们就会被转义并输出。如果我输入iex
,它会显示标准光束中断。我检查control-c
指向正确的地方而不是奇怪的别名,这似乎是正确的。我该如何解决此问题?
我已经尝试卸载并重新安装elixir(但还没有安装erlang),但这并没有解决它。我可以检查或删除任何缓存的文件吗?
答案 0 :(得分:0)
看here。我特别想到了这一部分:
.erlang启动文件
启动Erlang / OTP时,系统会在启动Erlang / OTP的目录中搜索名为.erlang的文件。如果没找到, 在用户的主目录中搜索.erlang文件。
如果找到.erlang文件,则假定它包含有效的Erlang表达式。这些表达式的评估就像输入它们一样 贝壳。
你想知道在任何地方是否有.erlang文件;这会改变Erl shell的启动。该页面还包含有关可能影响erl
行为的环境变量的一些细节。
答案 1 :(得分:0)
Ok, so turned out to be an erlang issue. After scouring my drive for erlang related files, I was able to get it to work after a re-install. Files I deleted before re-install:
~/.erlang.cookie
(the most likely candidate. contained a string similar to this: "AMVBSKDKEI", sadly, I don't have the exact string anymore)/usr/share/file/magic/erlang
looks to be part of file(1)
and not erlang directly. Left that alone and got it to work.